<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>TypeScrpit | 房飞跃的博客</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
    <link rel="icon" href="/favicon.ico">
    <link rel="manifest" href="/manifest.json">
    <meta name="description" content="房飞跃的博客">
    <meta name="theme-color" content="#ffffff">
    
    <link rel="preload" href="/assets/css/0.styles.e57fdc06.css" as="style"><link rel="preload" href="/assets/js/app.8c5a7a92.js" as="script"><link rel="preload" href="/assets/js/2.8e30e130.js" as="script"><link rel="preload" href="/assets/js/457.329d4d26.js" as="script"><link rel="preload" href="/assets/js/64.0323ed89.js" as="script"><link rel="prefetch" href="/assets/js/10.e695640a.js"><link rel="prefetch" href="/assets/js/100.fae9757f.js"><link rel="prefetch" href="/assets/js/101.d26f7a9a.js"><link rel="prefetch" href="/assets/js/102.e9b20f43.js"><link rel="prefetch" href="/assets/js/103.6d251ff3.js"><link rel="prefetch" href="/assets/js/104.5de918be.js"><link rel="prefetch" href="/assets/js/105.aead61a1.js"><link rel="prefetch" href="/assets/js/106.09a5decb.js"><link rel="prefetch" href="/assets/js/107.a44fc48a.js"><link rel="prefetch" href="/assets/js/108.cec63522.js"><link rel="prefetch" href="/assets/js/109.db1a4ed7.js"><link rel="prefetch" href="/assets/js/11.769ac82c.js"><link rel="prefetch" href="/assets/js/110.10914d38.js"><link rel="prefetch" href="/assets/js/111.2c0ddf25.js"><link rel="prefetch" href="/assets/js/112.c792ca07.js"><link rel="prefetch" href="/assets/js/113.a769ad8f.js"><link rel="prefetch" href="/assets/js/114.c1dca6a0.js"><link rel="prefetch" href="/assets/js/115.82e1fb4f.js"><link rel="prefetch" href="/assets/js/116.c927762b.js"><link rel="prefetch" href="/assets/js/117.5c14eedf.js"><link rel="prefetch" href="/assets/js/118.24861bb6.js"><link rel="prefetch" href="/assets/js/119.3fafaebf.js"><link rel="prefetch" href="/assets/js/12.23031504.js"><link rel="prefetch" href="/assets/js/120.a9ff8fae.js"><link rel="prefetch" href="/assets/js/121.3eb4b3a1.js"><link rel="prefetch" href="/assets/js/122.ff06cffe.js"><link rel="prefetch" href="/assets/js/123.aaf767a6.js"><link rel="prefetch" href="/assets/js/124.4daf257a.js"><link rel="prefetch" href="/assets/js/125.e7e71d3f.js"><link rel="prefetch" href="/assets/js/126.cdee6d86.js"><link rel="prefetch" href="/assets/js/127.aa133c3f.js"><link rel="prefetch" href="/assets/js/128.a8e7d8b2.js"><link rel="prefetch" href="/assets/js/129.dcca2d84.js"><link rel="prefetch" href="/assets/js/13.f37f647e.js"><link rel="prefetch" href="/assets/js/130.3925fb20.js"><link rel="prefetch" href="/assets/js/131.a3a759ed.js"><link rel="prefetch" href="/assets/js/132.84bb9bf9.js"><link rel="prefetch" href="/assets/js/133.30fceda7.js"><link rel="prefetch" href="/assets/js/134.e02f66bf.js"><link rel="prefetch" href="/assets/js/135.71a35d7f.js"><link rel="prefetch" href="/assets/js/136.77762773.js"><link rel="prefetch" href="/assets/js/137.b9741de3.js"><link rel="prefetch" href="/assets/js/138.59b64aa0.js"><link rel="prefetch" href="/assets/js/139.d81e68a1.js"><link rel="prefetch" href="/assets/js/14.0091824d.js"><link rel="prefetch" href="/assets/js/140.68388ddb.js"><link rel="prefetch" href="/assets/js/141.e69cc877.js"><link rel="prefetch" href="/assets/js/142.65fc1806.js"><link rel="prefetch" href="/assets/js/143.4f1e9b3d.js"><link rel="prefetch" href="/assets/js/144.5cf4bdda.js"><link rel="prefetch" href="/assets/js/145.1a1cdb18.js"><link rel="prefetch" href="/assets/js/146.ef4fe2c3.js"><link rel="prefetch" href="/assets/js/147.f5e5d206.js"><link rel="prefetch" href="/assets/js/148.07c7208f.js"><link rel="prefetch" href="/assets/js/149.fb71df8d.js"><link rel="prefetch" href="/assets/js/15.4e1991f3.js"><link rel="prefetch" href="/assets/js/150.771bcbfe.js"><link rel="prefetch" href="/assets/js/151.de02cd55.js"><link rel="prefetch" href="/assets/js/152.6a5b243d.js"><link rel="prefetch" href="/assets/js/153.c1c426d2.js"><link rel="prefetch" href="/assets/js/154.51e08a99.js"><link rel="prefetch" href="/assets/js/155.ab801c7a.js"><link rel="prefetch" href="/assets/js/156.e62111f0.js"><link rel="prefetch" href="/assets/js/157.67f19eb7.js"><link rel="prefetch" href="/assets/js/158.3e57553c.js"><link rel="prefetch" href="/assets/js/159.f01ea56a.js"><link rel="prefetch" href="/assets/js/16.aafe549d.js"><link rel="prefetch" href="/assets/js/160.81468500.js"><link rel="prefetch" href="/assets/js/161.8341c4c9.js"><link rel="prefetch" href="/assets/js/162.18cd1d1e.js"><link rel="prefetch" href="/assets/js/163.2ed65e27.js"><link rel="prefetch" href="/assets/js/164.1c0adbfd.js"><link rel="prefetch" href="/assets/js/165.4382f96e.js"><link rel="prefetch" href="/assets/js/166.47ad10ec.js"><link rel="prefetch" href="/assets/js/167.ee3e3de3.js"><link rel="prefetch" href="/assets/js/168.1273ebb0.js"><link rel="prefetch" href="/assets/js/169.bb6578e0.js"><link rel="prefetch" href="/assets/js/17.4548c40c.js"><link rel="prefetch" href="/assets/js/170.6aef0437.js"><link rel="prefetch" href="/assets/js/171.4818ad12.js"><link rel="prefetch" href="/assets/js/172.7f4674ed.js"><link rel="prefetch" href="/assets/js/173.25951cfa.js"><link rel="prefetch" href="/assets/js/174.604b8889.js"><link rel="prefetch" href="/assets/js/175.752d6221.js"><link rel="prefetch" href="/assets/js/176.ee6ccaf2.js"><link rel="prefetch" href="/assets/js/177.df3e7548.js"><link rel="prefetch" href="/assets/js/178.0c05bdea.js"><link rel="prefetch" href="/assets/js/179.fa300396.js"><link rel="prefetch" href="/assets/js/18.4a166581.js"><link rel="prefetch" href="/assets/js/180.78580e5a.js"><link rel="prefetch" href="/assets/js/181.c08c58e9.js"><link rel="prefetch" href="/assets/js/182.425fd44a.js"><link rel="prefetch" href="/assets/js/183.643e0376.js"><link rel="prefetch" href="/assets/js/184.28243fe4.js"><link rel="prefetch" href="/assets/js/185.145fafb0.js"><link rel="prefetch" href="/assets/js/186.9c005fb8.js"><link rel="prefetch" href="/assets/js/187.a1c8a8da.js"><link rel="prefetch" href="/assets/js/188.b78deff0.js"><link rel="prefetch" href="/assets/js/189.86432945.js"><link rel="prefetch" href="/assets/js/19.992da7e4.js"><link rel="prefetch" href="/assets/js/190.b6c616c9.js"><link rel="prefetch" href="/assets/js/191.d2a4a045.js"><link rel="prefetch" href="/assets/js/192.ce93c157.js"><link rel="prefetch" href="/assets/js/193.f45b56e8.js"><link rel="prefetch" href="/assets/js/194.60166b01.js"><link rel="prefetch" href="/assets/js/195.fea0fdcc.js"><link rel="prefetch" href="/assets/js/196.7f9353e4.js"><link rel="prefetch" href="/assets/js/197.2a8de731.js"><link rel="prefetch" href="/assets/js/198.6f3d807b.js"><link rel="prefetch" href="/assets/js/199.75028922.js"><link rel="prefetch" href="/assets/js/20.e27836ed.js"><link rel="prefetch" href="/assets/js/200.36fbe8e0.js"><link rel="prefetch" href="/assets/js/201.ca3a3d7d.js"><link rel="prefetch" href="/assets/js/202.8cc508cd.js"><link rel="prefetch" href="/assets/js/203.eb6662a4.js"><link rel="prefetch" href="/assets/js/204.a75edc0d.js"><link rel="prefetch" href="/assets/js/205.77cc7661.js"><link rel="prefetch" href="/assets/js/206.7cfc88ae.js"><link rel="prefetch" href="/assets/js/207.9d5b5377.js"><link rel="prefetch" href="/assets/js/208.9308a3b3.js"><link rel="prefetch" href="/assets/js/209.cbee10e7.js"><link rel="prefetch" href="/assets/js/21.9bc4424f.js"><link rel="prefetch" href="/assets/js/210.3dbd53b3.js"><link rel="prefetch" href="/assets/js/211.ffc0051e.js"><link rel="prefetch" href="/assets/js/212.420b9a23.js"><link rel="prefetch" href="/assets/js/213.da84f0aa.js"><link rel="prefetch" href="/assets/js/214.2a5308ff.js"><link rel="prefetch" href="/assets/js/215.bc87143e.js"><link rel="prefetch" href="/assets/js/216.f099b04d.js"><link rel="prefetch" href="/assets/js/217.39cc059e.js"><link rel="prefetch" href="/assets/js/218.3b588871.js"><link rel="prefetch" href="/assets/js/219.8c7c7f40.js"><link rel="prefetch" href="/assets/js/22.287b20ef.js"><link rel="prefetch" href="/assets/js/220.6a490188.js"><link rel="prefetch" href="/assets/js/221.a06fe7b9.js"><link rel="prefetch" href="/assets/js/222.0da34a82.js"><link rel="prefetch" href="/assets/js/223.6d6abad9.js"><link rel="prefetch" href="/assets/js/224.de157359.js"><link rel="prefetch" href="/assets/js/225.c733d3d1.js"><link rel="prefetch" href="/assets/js/226.039d453b.js"><link rel="prefetch" href="/assets/js/227.dbe84815.js"><link rel="prefetch" href="/assets/js/228.4850e3f3.js"><link rel="prefetch" href="/assets/js/229.322215a9.js"><link rel="prefetch" href="/assets/js/23.c1fc6d56.js"><link rel="prefetch" href="/assets/js/230.2469fb45.js"><link rel="prefetch" href="/assets/js/231.a77224ae.js"><link rel="prefetch" href="/assets/js/232.56534eb1.js"><link rel="prefetch" href="/assets/js/233.f69b682d.js"><link rel="prefetch" href="/assets/js/234.33fecaf9.js"><link rel="prefetch" href="/assets/js/235.3152a6d8.js"><link rel="prefetch" href="/assets/js/236.4a45a619.js"><link rel="prefetch" href="/assets/js/237.683796c5.js"><link rel="prefetch" href="/assets/js/238.4183baab.js"><link rel="prefetch" href="/assets/js/239.967342f3.js"><link rel="prefetch" href="/assets/js/24.c4266153.js"><link rel="prefetch" href="/assets/js/240.4ebdaa3e.js"><link rel="prefetch" href="/assets/js/241.3853f81e.js"><link rel="prefetch" href="/assets/js/242.0be00241.js"><link rel="prefetch" href="/assets/js/243.27a16565.js"><link rel="prefetch" href="/assets/js/244.4b6c0842.js"><link rel="prefetch" href="/assets/js/245.0ff5b09e.js"><link rel="prefetch" href="/assets/js/246.ec9708bc.js"><link rel="prefetch" href="/assets/js/247.33dd2e3f.js"><link rel="prefetch" href="/assets/js/248.e095c83d.js"><link rel="prefetch" href="/assets/js/249.e35dae0b.js"><link rel="prefetch" href="/assets/js/25.0bd19957.js"><link rel="prefetch" href="/assets/js/250.b7dda30b.js"><link rel="prefetch" href="/assets/js/251.373c219f.js"><link rel="prefetch" href="/assets/js/252.f02d8652.js"><link rel="prefetch" href="/assets/js/253.0129ab3b.js"><link rel="prefetch" href="/assets/js/254.05bc87ae.js"><link rel="prefetch" href="/assets/js/255.93959060.js"><link rel="prefetch" href="/assets/js/256.036268bb.js"><link rel="prefetch" href="/assets/js/257.4cfe4c46.js"><link rel="prefetch" href="/assets/js/258.70f49e1e.js"><link rel="prefetch" href="/assets/js/259.e92d7a7e.js"><link rel="prefetch" href="/assets/js/26.cd8cc5bc.js"><link rel="prefetch" href="/assets/js/260.24ecb139.js"><link rel="prefetch" href="/assets/js/261.32f0c433.js"><link rel="prefetch" href="/assets/js/262.aca4b5e9.js"><link rel="prefetch" href="/assets/js/263.0051554a.js"><link rel="prefetch" href="/assets/js/264.063d3092.js"><link rel="prefetch" href="/assets/js/265.de1fe60c.js"><link rel="prefetch" href="/assets/js/266.4407a594.js"><link rel="prefetch" href="/assets/js/267.9318dca9.js"><link rel="prefetch" href="/assets/js/268.b9696b4c.js"><link rel="prefetch" href="/assets/js/269.21743bc6.js"><link rel="prefetch" href="/assets/js/27.e0c9a2d1.js"><link rel="prefetch" href="/assets/js/270.64175904.js"><link rel="prefetch" href="/assets/js/271.ab988e51.js"><link rel="prefetch" href="/assets/js/272.40190656.js"><link rel="prefetch" href="/assets/js/273.124f97d6.js"><link rel="prefetch" href="/assets/js/274.ac2ae949.js"><link rel="prefetch" href="/assets/js/275.84112c31.js"><link rel="prefetch" href="/assets/js/276.5cd3a2f1.js"><link rel="prefetch" href="/assets/js/277.dfd266d2.js"><link rel="prefetch" href="/assets/js/278.2c22b507.js"><link rel="prefetch" href="/assets/js/279.143630b9.js"><link rel="prefetch" href="/assets/js/28.ee8b098b.js"><link rel="prefetch" href="/assets/js/280.e52e72d5.js"><link rel="prefetch" href="/assets/js/281.fa255716.js"><link rel="prefetch" href="/assets/js/282.33cf3680.js"><link rel="prefetch" href="/assets/js/283.8aaeb880.js"><link rel="prefetch" href="/assets/js/284.cce2c80c.js"><link rel="prefetch" href="/assets/js/285.649e1ab2.js"><link rel="prefetch" href="/assets/js/286.93d1a5fb.js"><link rel="prefetch" href="/assets/js/287.95ecc60d.js"><link rel="prefetch" href="/assets/js/288.d0316c60.js"><link rel="prefetch" href="/assets/js/289.96b0da90.js"><link rel="prefetch" href="/assets/js/29.f1800df7.js"><link rel="prefetch" href="/assets/js/290.a0ec1eb0.js"><link rel="prefetch" href="/assets/js/291.000c9293.js"><link rel="prefetch" href="/assets/js/292.aa442a45.js"><link rel="prefetch" href="/assets/js/293.ad41a62d.js"><link rel="prefetch" href="/assets/js/294.d01fa093.js"><link rel="prefetch" href="/assets/js/295.988cbaa2.js"><link rel="prefetch" href="/assets/js/296.b4376d7c.js"><link rel="prefetch" href="/assets/js/297.53d3839b.js"><link rel="prefetch" href="/assets/js/298.e41d3af5.js"><link rel="prefetch" href="/assets/js/299.7530e3f7.js"><link rel="prefetch" href="/assets/js/3.0318d431.js"><link rel="prefetch" href="/assets/js/30.e022632d.js"><link rel="prefetch" href="/assets/js/300.b89cf9f0.js"><link rel="prefetch" href="/assets/js/301.538c5d13.js"><link rel="prefetch" href="/assets/js/302.e61e98d4.js"><link rel="prefetch" href="/assets/js/303.e69fdf1f.js"><link rel="prefetch" href="/assets/js/304.12cf05d2.js"><link rel="prefetch" href="/assets/js/305.05630898.js"><link rel="prefetch" href="/assets/js/306.4423e4cb.js"><link rel="prefetch" href="/assets/js/307.ec499705.js"><link rel="prefetch" href="/assets/js/308.eae04a19.js"><link rel="prefetch" href="/assets/js/309.e8cdb29d.js"><link rel="prefetch" href="/assets/js/31.a2dfbc5f.js"><link rel="prefetch" href="/assets/js/310.3770a9fc.js"><link rel="prefetch" href="/assets/js/311.79ae7adb.js"><link rel="prefetch" href="/assets/js/312.fd3baefc.js"><link rel="prefetch" href="/assets/js/313.895f6dcd.js"><link rel="prefetch" href="/assets/js/314.85943d2f.js"><link rel="prefetch" href="/assets/js/315.69631810.js"><link rel="prefetch" href="/assets/js/316.b025621c.js"><link rel="prefetch" href="/assets/js/317.7b7974aa.js"><link rel="prefetch" href="/assets/js/318.972a129d.js"><link rel="prefetch" href="/assets/js/319.65a4d2cf.js"><link rel="prefetch" href="/assets/js/32.b143e718.js"><link rel="prefetch" href="/assets/js/320.e5635579.js"><link rel="prefetch" href="/assets/js/321.845573fa.js"><link rel="prefetch" href="/assets/js/322.0f95ad9a.js"><link rel="prefetch" href="/assets/js/323.f7d22184.js"><link rel="prefetch" href="/assets/js/324.eb027f24.js"><link rel="prefetch" href="/assets/js/325.f54af6ec.js"><link rel="prefetch" href="/assets/js/326.7a921d9f.js"><link rel="prefetch" href="/assets/js/327.e9c43c17.js"><link rel="prefetch" href="/assets/js/328.586efc33.js"><link rel="prefetch" href="/assets/js/329.47017c3f.js"><link rel="prefetch" href="/assets/js/33.e17e09ac.js"><link rel="prefetch" href="/assets/js/330.81032fbd.js"><link rel="prefetch" href="/assets/js/331.ce9966db.js"><link rel="prefetch" href="/assets/js/332.c28e794e.js"><link rel="prefetch" href="/assets/js/333.4564d08a.js"><link rel="prefetch" href="/assets/js/334.3b421837.js"><link rel="prefetch" href="/assets/js/335.b2b74b9d.js"><link rel="prefetch" href="/assets/js/336.9dd1e510.js"><link rel="prefetch" href="/assets/js/337.03042431.js"><link rel="prefetch" href="/assets/js/338.1bc0b80f.js"><link rel="prefetch" href="/assets/js/339.e517fc5c.js"><link rel="prefetch" href="/assets/js/34.f287ac3d.js"><link rel="prefetch" href="/assets/js/340.f90d2df3.js"><link rel="prefetch" href="/assets/js/341.eccb4ec1.js"><link rel="prefetch" href="/assets/js/342.b3386439.js"><link rel="prefetch" href="/assets/js/343.2ee6901d.js"><link rel="prefetch" href="/assets/js/344.e6913fc7.js"><link rel="prefetch" href="/assets/js/345.a72760e7.js"><link rel="prefetch" href="/assets/js/346.13984d25.js"><link rel="prefetch" href="/assets/js/347.6b59cbaf.js"><link rel="prefetch" href="/assets/js/348.f43d5e47.js"><link rel="prefetch" href="/assets/js/349.fe8641cf.js"><link rel="prefetch" href="/assets/js/35.5a1dace7.js"><link rel="prefetch" href="/assets/js/350.0ceb9652.js"><link rel="prefetch" href="/assets/js/351.08e70696.js"><link rel="prefetch" href="/assets/js/352.958f535b.js"><link rel="prefetch" href="/assets/js/353.51463d78.js"><link rel="prefetch" href="/assets/js/354.6169e165.js"><link rel="prefetch" href="/assets/js/355.10447463.js"><link rel="prefetch" href="/assets/js/356.32983151.js"><link rel="prefetch" href="/assets/js/357.39e998b6.js"><link rel="prefetch" href="/assets/js/358.1f40aee7.js"><link rel="prefetch" href="/assets/js/359.d1e82e86.js"><link rel="prefetch" href="/assets/js/36.b6f4332a.js"><link rel="prefetch" href="/assets/js/360.9096bf48.js"><link rel="prefetch" href="/assets/js/361.e2c0815a.js"><link rel="prefetch" href="/assets/js/362.66983024.js"><link rel="prefetch" href="/assets/js/363.d7f0691d.js"><link rel="prefetch" href="/assets/js/364.d96ddc65.js"><link rel="prefetch" href="/assets/js/365.c92ad624.js"><link rel="prefetch" href="/assets/js/366.dfd66280.js"><link rel="prefetch" href="/assets/js/367.01503521.js"><link rel="prefetch" href="/assets/js/368.8d83b9c1.js"><link rel="prefetch" href="/assets/js/369.f8e08a4f.js"><link rel="prefetch" href="/assets/js/37.f1a16008.js"><link rel="prefetch" href="/assets/js/370.70b912f3.js"><link rel="prefetch" href="/assets/js/371.dcefb388.js"><link rel="prefetch" href="/assets/js/372.a81a499a.js"><link rel="prefetch" href="/assets/js/373.94458b0f.js"><link rel="prefetch" href="/assets/js/374.a406f06f.js"><link rel="prefetch" href="/assets/js/375.87287c02.js"><link rel="prefetch" href="/assets/js/376.26088425.js"><link rel="prefetch" href="/assets/js/377.b9ee096c.js"><link rel="prefetch" href="/assets/js/378.7a1b6fa7.js"><link rel="prefetch" href="/assets/js/379.3e2b62fc.js"><link rel="prefetch" href="/assets/js/38.59f5160c.js"><link rel="prefetch" href="/assets/js/380.d741385f.js"><link rel="prefetch" href="/assets/js/381.afc0104a.js"><link rel="prefetch" href="/assets/js/382.a8c02915.js"><link rel="prefetch" href="/assets/js/383.7fca9756.js"><link rel="prefetch" href="/assets/js/384.d08aa931.js"><link rel="prefetch" href="/assets/js/385.c3ab471f.js"><link rel="prefetch" href="/assets/js/386.7314b80e.js"><link rel="prefetch" href="/assets/js/387.8db3a14a.js"><link rel="prefetch" href="/assets/js/388.f618a3b3.js"><link rel="prefetch" href="/assets/js/389.4d35947d.js"><link rel="prefetch" href="/assets/js/39.3cf9af40.js"><link rel="prefetch" href="/assets/js/390.a8e04e41.js"><link rel="prefetch" href="/assets/js/391.a31e9a62.js"><link rel="prefetch" href="/assets/js/392.d9321e46.js"><link rel="prefetch" href="/assets/js/393.6c4834d0.js"><link rel="prefetch" href="/assets/js/394.fd0a0ea4.js"><link rel="prefetch" href="/assets/js/395.0f27ab48.js"><link rel="prefetch" href="/assets/js/396.70044e25.js"><link rel="prefetch" href="/assets/js/397.07b2c0a6.js"><link rel="prefetch" href="/assets/js/398.ba95a9c5.js"><link rel="prefetch" href="/assets/js/399.8b310fbc.js"><link rel="prefetch" href="/assets/js/4.45f61616.js"><link rel="prefetch" href="/assets/js/40.fcf089d7.js"><link rel="prefetch" href="/assets/js/400.7ff77c6c.js"><link rel="prefetch" href="/assets/js/401.840e0c7c.js"><link rel="prefetch" href="/assets/js/402.a722c16f.js"><link rel="prefetch" href="/assets/js/403.1a3c12fb.js"><link rel="prefetch" href="/assets/js/404.7da4d4a4.js"><link rel="prefetch" href="/assets/js/405.76a07310.js"><link rel="prefetch" href="/assets/js/406.176db1fd.js"><link rel="prefetch" href="/assets/js/407.ff3da33f.js"><link rel="prefetch" href="/assets/js/408.3b4dfb3a.js"><link rel="prefetch" href="/assets/js/409.05692a2e.js"><link rel="prefetch" href="/assets/js/41.3f0a746d.js"><link rel="prefetch" href="/assets/js/410.615dc40b.js"><link rel="prefetch" href="/assets/js/411.e542a59f.js"><link rel="prefetch" href="/assets/js/412.16fc0c97.js"><link rel="prefetch" href="/assets/js/413.b9f30c37.js"><link rel="prefetch" href="/assets/js/414.9629300e.js"><link rel="prefetch" href="/assets/js/415.5c12951e.js"><link rel="prefetch" href="/assets/js/416.3ede10bc.js"><link rel="prefetch" href="/assets/js/417.5bc08adb.js"><link rel="prefetch" href="/assets/js/418.0a54fe32.js"><link rel="prefetch" href="/assets/js/419.97ebd724.js"><link rel="prefetch" href="/assets/js/42.d0fdcdd4.js"><link rel="prefetch" href="/assets/js/420.d3f60a7a.js"><link rel="prefetch" href="/assets/js/421.6b187cc9.js"><link rel="prefetch" href="/assets/js/422.268b38aa.js"><link rel="prefetch" href="/assets/js/423.00f151fe.js"><link rel="prefetch" href="/assets/js/424.5d54e48d.js"><link rel="prefetch" href="/assets/js/425.b0e71df6.js"><link rel="prefetch" href="/assets/js/426.fb5d6c08.js"><link rel="prefetch" href="/assets/js/427.a7a42bdb.js"><link rel="prefetch" href="/assets/js/428.b41b80fb.js"><link rel="prefetch" href="/assets/js/429.aff3b223.js"><link rel="prefetch" href="/assets/js/43.7812871c.js"><link rel="prefetch" href="/assets/js/430.9bded6a2.js"><link rel="prefetch" href="/assets/js/431.fbd064dd.js"><link rel="prefetch" href="/assets/js/432.a0ccaf13.js"><link rel="prefetch" href="/assets/js/433.70729631.js"><link rel="prefetch" href="/assets/js/434.7ff21dc4.js"><link rel="prefetch" href="/assets/js/435.ba6f0c33.js"><link rel="prefetch" href="/assets/js/436.abcca44e.js"><link rel="prefetch" href="/assets/js/437.2b2333cb.js"><link rel="prefetch" href="/assets/js/438.93ea3d14.js"><link rel="prefetch" href="/assets/js/439.c1b946ea.js"><link rel="prefetch" href="/assets/js/44.d2bbbf62.js"><link rel="prefetch" href="/assets/js/440.a5c5071e.js"><link rel="prefetch" href="/assets/js/441.bad7a6f2.js"><link rel="prefetch" href="/assets/js/442.97a45e71.js"><link rel="prefetch" href="/assets/js/443.9dd7a744.js"><link rel="prefetch" href="/assets/js/444.b2e74ec9.js"><link rel="prefetch" href="/assets/js/445.181b11ad.js"><link rel="prefetch" href="/assets/js/446.1d43ea57.js"><link rel="prefetch" href="/assets/js/447.a75ca861.js"><link rel="prefetch" href="/assets/js/448.7e177e61.js"><link rel="prefetch" href="/assets/js/449.0e124a1f.js"><link rel="prefetch" href="/assets/js/45.2181b5c6.js"><link rel="prefetch" href="/assets/js/450.d18c5137.js"><link rel="prefetch" href="/assets/js/451.0296f837.js"><link rel="prefetch" href="/assets/js/452.1f5d56a5.js"><link rel="prefetch" href="/assets/js/453.6f67fa9b.js"><link rel="prefetch" href="/assets/js/454.d96cd4e8.js"><link rel="prefetch" href="/assets/js/455.488f2e23.js"><link rel="prefetch" href="/assets/js/456.264d0da2.js"><link rel="prefetch" href="/assets/js/458.d20d34f9.js"><link rel="prefetch" href="/assets/js/459.dd4fad09.js"><link rel="prefetch" href="/assets/js/46.d69710e9.js"><link rel="prefetch" href="/assets/js/460.e1f8580c.js"><link rel="prefetch" href="/assets/js/461.d47e1ab7.js"><link rel="prefetch" href="/assets/js/462.54b49f34.js"><link rel="prefetch" href="/assets/js/463.2d1bb289.js"><link rel="prefetch" href="/assets/js/464.28d2b2fe.js"><link rel="prefetch" href="/assets/js/465.474d09dd.js"><link rel="prefetch" href="/assets/js/466.3d79bf1d.js"><link rel="prefetch" href="/assets/js/467.0e38992e.js"><link rel="prefetch" href="/assets/js/468.23f8dbdb.js"><link rel="prefetch" href="/assets/js/469.424ab64e.js"><link rel="prefetch" href="/assets/js/47.fa77c18f.js"><link rel="prefetch" href="/assets/js/470.8e15adc4.js"><link rel="prefetch" href="/assets/js/471.e478b277.js"><link rel="prefetch" href="/assets/js/472.75eed247.js"><link rel="prefetch" href="/assets/js/473.676ac02f.js"><link rel="prefetch" href="/assets/js/474.ec676f10.js"><link rel="prefetch" href="/assets/js/475.0b3a7bb3.js"><link rel="prefetch" href="/assets/js/476.1dccc2bf.js"><link rel="prefetch" href="/assets/js/477.19774d6a.js"><link rel="prefetch" href="/assets/js/478.562bcdfb.js"><link rel="prefetch" href="/assets/js/479.0fdf39e1.js"><link rel="prefetch" href="/assets/js/48.55ba7067.js"><link rel="prefetch" href="/assets/js/480.32cb0959.js"><link rel="prefetch" href="/assets/js/481.39744803.js"><link rel="prefetch" href="/assets/js/482.82ff750c.js"><link rel="prefetch" href="/assets/js/483.59be5f3b.js"><link rel="prefetch" href="/assets/js/484.b47730ba.js"><link rel="prefetch" href="/assets/js/485.514e284f.js"><link rel="prefetch" href="/assets/js/486.8d407228.js"><link rel="prefetch" href="/assets/js/487.623afb9a.js"><link rel="prefetch" href="/assets/js/488.d575377d.js"><link rel="prefetch" href="/assets/js/49.369b2ef4.js"><link rel="prefetch" href="/assets/js/5.89e027e6.js"><link rel="prefetch" href="/assets/js/50.32e51808.js"><link rel="prefetch" href="/assets/js/51.48af1f55.js"><link rel="prefetch" href="/assets/js/52.0ff3366f.js"><link rel="prefetch" href="/assets/js/53.f663d530.js"><link rel="prefetch" href="/assets/js/54.57eabb55.js"><link rel="prefetch" href="/assets/js/55.00e0bdd0.js"><link rel="prefetch" href="/assets/js/56.b638bc9a.js"><link rel="prefetch" href="/assets/js/57.68420705.js"><link rel="prefetch" href="/assets/js/58.f0a325a2.js"><link rel="prefetch" href="/assets/js/59.30debc93.js"><link rel="prefetch" href="/assets/js/6.0db48d19.js"><link rel="prefetch" href="/assets/js/60.48490f44.js"><link rel="prefetch" href="/assets/js/61.26a984a9.js"><link rel="prefetch" href="/assets/js/62.f0add27d.js"><link rel="prefetch" href="/assets/js/63.07c42d31.js"><link rel="prefetch" href="/assets/js/65.c159a057.js"><link rel="prefetch" href="/assets/js/66.80e96020.js"><link rel="prefetch" href="/assets/js/67.42eabf7d.js"><link rel="prefetch" href="/assets/js/68.2a7e9954.js"><link rel="prefetch" href="/assets/js/69.4579e421.js"><link rel="prefetch" href="/assets/js/7.037ecfb1.js"><link rel="prefetch" href="/assets/js/70.4e7b95d4.js"><link rel="prefetch" href="/assets/js/71.5df75825.js"><link rel="prefetch" href="/assets/js/72.6239ec2a.js"><link rel="prefetch" href="/assets/js/73.c2458335.js"><link rel="prefetch" href="/assets/js/74.b86599e1.js"><link rel="prefetch" href="/assets/js/75.8d14cab7.js"><link rel="prefetch" href="/assets/js/76.82bf4b00.js"><link rel="prefetch" href="/assets/js/77.f5a890cc.js"><link rel="prefetch" href="/assets/js/78.f3c574f3.js"><link rel="prefetch" href="/assets/js/79.c9c56bf3.js"><link rel="prefetch" href="/assets/js/8.03d32196.js"><link rel="prefetch" href="/assets/js/80.24c4483b.js"><link rel="prefetch" href="/assets/js/81.e6653250.js"><link rel="prefetch" href="/assets/js/82.0da4ae5d.js"><link rel="prefetch" href="/assets/js/83.89a8c965.js"><link rel="prefetch" href="/assets/js/84.56206c88.js"><link rel="prefetch" href="/assets/js/85.0daf7cf7.js"><link rel="prefetch" href="/assets/js/86.0a17b684.js"><link rel="prefetch" href="/assets/js/87.f7cf9412.js"><link rel="prefetch" href="/assets/js/88.22341e3f.js"><link rel="prefetch" href="/assets/js/89.2166c8bb.js"><link rel="prefetch" href="/assets/js/9.a241a058.js"><link rel="prefetch" href="/assets/js/90.9440815d.js"><link rel="prefetch" href="/assets/js/91.5ea69e27.js"><link rel="prefetch" href="/assets/js/92.cea1c8dd.js"><link rel="prefetch" href="/assets/js/93.2e94ab93.js"><link rel="prefetch" href="/assets/js/94.1674ba0c.js"><link rel="prefetch" href="/assets/js/95.c6ba057e.js"><link rel="prefetch" href="/assets/js/96.ee719565.js"><link rel="prefetch" href="/assets/js/97.a814f163.js"><link rel="prefetch" href="/assets/js/98.748b1098.js"><link rel="prefetch" href="/assets/js/99.c6176c0d.js">
    <link rel="stylesheet" href="/assets/css/0.styles.e57fdc06.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo.png" alt="房飞跃的博客" class="logo"> <span class="site-name can-hide">房飞跃的博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><span class="title">前端</span> <span class="arrow down"></span></button> <button type="button" aria-label="前端" class="mobile-dropdown-title"><span class="title">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          Vue
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入浅出Vue.js/01.html" class="nav-link">
  深入浅出Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue/01.html" class="nav-link">
  Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue-router/01.html" class="nav-link">
  VueRouter
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vuex/01.html" class="nav-link">
  Vuex
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue3/01.html" class="nav-link">
  Vue3核心剖析
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vue知识点简单梳理/01.html" class="nav-link">
  Vue知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          React
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入React技术栈/01.html" class="nav-link">
  深入React技术栈
</a></li><li class="dropdown-subitem"><a href="/front/react/React进阶实践指南/01.html" class="nav-link">
  React进阶实践指南
</a></li><li class="dropdown-subitem"><a href="/front/react/React知识点简单梳理/01.html" class="nav-link">
  React知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          混合开发
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/混合开发/01.html" class="nav-link">
  混合开发探究
</a></li></ul></li><li class="dropdown-item"><h4>
          TypeScript
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/ts/极简入门Typescript/01.html" class="nav-link">
  极简入门Typescript
</a></li></ul></li><li class="dropdown-item"><h4>
          Webpack
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/webpack/极简入门webpack/01.html" class="nav-link">
  极简入门
</a></li><li class="dropdown-subitem"><a href="/front/webpack/常见面试题/01.html" class="nav-link">
  常见面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          设计模式
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/设计模式/JS设计模式核心原理和应用实践/01.html" class="nav-link">
  JS设计模式核心原理和应用实践
</a></li></ul></li><li class="dropdown-item"><h4>
          算法和数据结构
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/算法和数据结构/入门级算法/01.html" class="nav-link">
  入门级算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见算法/01.html" class="nav-link">
  常见算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见数据结构/01.html" class="nav-link">
  常见数据结构
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/前端算法与数据结构/01.html" class="nav-link">
  前端算法与数据结构
</a></li></ul></li><li class="dropdown-item"><h4>
          基础必备
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/base/html必备/01.html" class="nav-link">
  HTML必备
</a></li><li class="dropdown-subitem"><a href="/front/base/CSS必备/01.html" class="nav-link">
  CSS必备
</a></li><li class="dropdown-subitem"><a href="/front/base/JS基础/01.html" class="nav-link">
  JS基础
</a></li><li class="dropdown-subitem"><a href="/front/base/JS进阶/01.html" class="nav-link">
  JS进阶
</a></li><li class="dropdown-subitem"><a href="/front/base/JS练习/01.html" class="nav-link">
  JS练习
</a></li><li class="dropdown-subitem"><a href="/front/base/网络基础/01.html" class="nav-link">
  网络基础
</a></li><li class="dropdown-subitem"><a href="/books/JS高级程序设计/01.html" class="nav-link">
  JS高级程序设计
</a></li><li class="dropdown-subitem"><a href="/front/base/浏览器相关基础/01.html" class="nav-link">
  浏览器相关基础
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="电子" class="dropdown-title"><span class="title">电子</span> <span class="arrow down"></span></button> <button type="button" aria-label="电子" class="mobile-dropdown-title"><span class="title">电子</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          STM32
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/STM32四轴飞行器/01.html" class="nav-link">
  STM32四轴飞行器
</a></li></ul></li><li class="dropdown-item"><h4>
          Arduino
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/Arduino墙画机/01.html" class="nav-link">
  Arduino墙画机
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四轴飞行器/01.html" class="nav-link">
  Arduino四轴飞行器
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四足仿生机器人/01.html" class="nav-link">
  Arduino四足仿生机器人
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关于" class="dropdown-title"><span class="title">关于</span> <span class="arrow down"></span></button> <button type="button" aria-label="关于" class="mobile-dropdown-title"><span class="title">关于</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/关于我/01.html" class="nav-link">
  关于我
</a></li><li class="dropdown-item"><!----> <a href="https://github.com/fangfeiyue" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><span class="title">前端</span> <span class="arrow down"></span></button> <button type="button" aria-label="前端" class="mobile-dropdown-title"><span class="title">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          Vue
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入浅出Vue.js/01.html" class="nav-link">
  深入浅出Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue/01.html" class="nav-link">
  Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue-router/01.html" class="nav-link">
  VueRouter
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vuex/01.html" class="nav-link">
  Vuex
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue3/01.html" class="nav-link">
  Vue3核心剖析
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vue知识点简单梳理/01.html" class="nav-link">
  Vue知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          React
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入React技术栈/01.html" class="nav-link">
  深入React技术栈
</a></li><li class="dropdown-subitem"><a href="/front/react/React进阶实践指南/01.html" class="nav-link">
  React进阶实践指南
</a></li><li class="dropdown-subitem"><a href="/front/react/React知识点简单梳理/01.html" class="nav-link">
  React知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          混合开发
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/混合开发/01.html" class="nav-link">
  混合开发探究
</a></li></ul></li><li class="dropdown-item"><h4>
          TypeScript
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/ts/极简入门Typescript/01.html" class="nav-link">
  极简入门Typescript
</a></li></ul></li><li class="dropdown-item"><h4>
          Webpack
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/webpack/极简入门webpack/01.html" class="nav-link">
  极简入门
</a></li><li class="dropdown-subitem"><a href="/front/webpack/常见面试题/01.html" class="nav-link">
  常见面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          设计模式
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/设计模式/JS设计模式核心原理和应用实践/01.html" class="nav-link">
  JS设计模式核心原理和应用实践
</a></li></ul></li><li class="dropdown-item"><h4>
          算法和数据结构
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/算法和数据结构/入门级算法/01.html" class="nav-link">
  入门级算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见算法/01.html" class="nav-link">
  常见算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见数据结构/01.html" class="nav-link">
  常见数据结构
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/前端算法与数据结构/01.html" class="nav-link">
  前端算法与数据结构
</a></li></ul></li><li class="dropdown-item"><h4>
          基础必备
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/base/html必备/01.html" class="nav-link">
  HTML必备
</a></li><li class="dropdown-subitem"><a href="/front/base/CSS必备/01.html" class="nav-link">
  CSS必备
</a></li><li class="dropdown-subitem"><a href="/front/base/JS基础/01.html" class="nav-link">
  JS基础
</a></li><li class="dropdown-subitem"><a href="/front/base/JS进阶/01.html" class="nav-link">
  JS进阶
</a></li><li class="dropdown-subitem"><a href="/front/base/JS练习/01.html" class="nav-link">
  JS练习
</a></li><li class="dropdown-subitem"><a href="/front/base/网络基础/01.html" class="nav-link">
  网络基础
</a></li><li class="dropdown-subitem"><a href="/books/JS高级程序设计/01.html" class="nav-link">
  JS高级程序设计
</a></li><li class="dropdown-subitem"><a href="/front/base/浏览器相关基础/01.html" class="nav-link">
  浏览器相关基础
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="电子" class="dropdown-title"><span class="title">电子</span> <span class="arrow down"></span></button> <button type="button" aria-label="电子" class="mobile-dropdown-title"><span class="title">电子</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          STM32
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/STM32四轴飞行器/01.html" class="nav-link">
  STM32四轴飞行器
</a></li></ul></li><li class="dropdown-item"><h4>
          Arduino
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/Arduino墙画机/01.html" class="nav-link">
  Arduino墙画机
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四轴飞行器/01.html" class="nav-link">
  Arduino四轴飞行器
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四足仿生机器人/01.html" class="nav-link">
  Arduino四足仿生机器人
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关于" class="dropdown-title"><span class="title">关于</span> <span class="arrow down"></span></button> <button type="button" aria-label="关于" class="mobile-dropdown-title"><span class="title">关于</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/关于我/01.html" class="nav-link">
  关于我
</a></li><li class="dropdown-item"><!----> <a href="https://github.com/fangfeiyue" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>TypeScrpit</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/typescript/#typescrpit的安装和编译" class="sidebar-link">TypeScrpit的安装和编译</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#安装" class="sidebar-link">安装</a></li></ul></li><li><a href="/typescript/#数据类型" class="sidebar-link">数据类型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#布尔类型" class="sidebar-link">布尔类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#数字类型-number" class="sidebar-link">数字类型(number)</a></li><li class="sidebar-sub-header"><a href="/typescript/#字符串类型-string" class="sidebar-link">字符串类型(string)</a></li><li class="sidebar-sub-header"><a href="/typescript/#数组类型-array" class="sidebar-link">数组类型(array)</a></li><li class="sidebar-sub-header"><a href="/typescript/#元组类型-tuple" class="sidebar-link">元组类型(tuple)</a></li><li class="sidebar-sub-header"><a href="/typescript/#枚举类型" class="sidebar-link">枚举类型</a></li></ul></li><li><a href="/typescript/#接口" class="sidebar-link">接口</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#对象的形状" class="sidebar-link">对象的形状</a></li><li class="sidebar-sub-header"><a href="/typescript/#行为的抽象" class="sidebar-link">行为的抽象</a></li><li class="sidebar-sub-header"><a href="/typescript/#任意属性" class="sidebar-link">任意属性</a></li><li class="sidebar-sub-header"><a href="/typescript/#接口的继承" class="sidebar-link">接口的继承</a></li><li class="sidebar-sub-header"><a href="/typescript/#readonly" class="sidebar-link">readonly</a></li><li class="sidebar-sub-header"><a href="/typescript/#函数类型接口" class="sidebar-link">函数类型接口</a></li><li class="sidebar-sub-header"><a href="/typescript/#可索引接口" class="sidebar-link">可索引接口</a></li><li class="sidebar-sub-header"><a href="/typescript/#类接口" class="sidebar-link">类接口</a></li><li class="sidebar-sub-header"><a href="/typescript/#构造函数的类型" class="sidebar-link">构造函数的类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#抽象类-vs-接口" class="sidebar-link">抽象类 vs 接口</a></li></ul></li><li><a href="/typescript/#泛型接口" class="sidebar-link">泛型接口</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#typeof-类型保护" class="sidebar-link">typeof 类型保护</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#instanceof类型保护" class="sidebar-link">instanceof类型保护</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#null保护" class="sidebar-link">null保护</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#链判断运算符" class="sidebar-link">链判断运算符</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#可辨识的联合类型" class="sidebar-link">可辨识的联合类型</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#in操作符" class="sidebar-link">in操作符</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#自定义的类型保护" class="sidebar-link">自定义的类型保护</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#unknown" class="sidebar-link">unknown</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#any-类型" class="sidebar-link">any 类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#unknown-类型" class="sidebar-link">unknown 类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#缩小-unknown-类型范围" class="sidebar-link">缩小 unknown 类型范围</a></li><li class="sidebar-sub-header"><a href="/typescript/#联合类型中的-unknown-类型" class="sidebar-link">联合类型中的 unknown 类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#交叉类型中的-unknown-类型" class="sidebar-link">交叉类型中的 unknown 类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#never是unknown的子类型" class="sidebar-link">never是unknown的子类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#keyof-unknown-等于never" class="sidebar-link">keyof unknown 等于never</a></li><li class="sidebar-sub-header"><a href="/typescript/#只能对unknown进行等或不等操作-不能进行其它操作" class="sidebar-link">只能对unknown进行等或不等操作，不能进行其它操作</a></li><li class="sidebar-sub-header"><a href="/typescript/#不能做任何操作" class="sidebar-link">不能做任何操作</a></li><li class="sidebar-sub-header"><a href="/typescript/#映射属性" class="sidebar-link">映射属性</a></li></ul></li><li><a href="/typescript/#类型推断" class="sidebar-link">类型推断</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#从右向左" class="sidebar-link">从右向左</a></li><li class="sidebar-sub-header"><a href="/typescript/#底部流出" class="sidebar-link">底部流出</a></li><li class="sidebar-sub-header"><a href="/typescript/#从左向右" class="sidebar-link">从左向右</a></li><li class="sidebar-sub-header"><a href="/typescript/#结构化" class="sidebar-link">结构化</a></li><li class="sidebar-sub-header"><a href="/typescript/#解构" class="sidebar-link">解构</a></li><li class="sidebar-sub-header"><a href="/typescript/#defaultprops" class="sidebar-link">DefaultProps</a></li><li class="sidebar-sub-header"><a href="/typescript/#小心使用返回值" class="sidebar-link">小心使用返回值</a></li></ul></li><li><a href="/typescript/#交叉类型" class="sidebar-link">交叉类型</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#typeof" class="sidebar-link">typeof</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#索引访问操作符" class="sidebar-link">索引访问操作符</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#keyof" class="sidebar-link">keyof</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#映射类型" class="sidebar-link">映射类型</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#条件类型" class="sidebar-link">条件类型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#定义条件类型" class="sidebar-link">定义条件类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#条件类型的分发" class="sidebar-link">条件类型的分发</a></li></ul></li><li><a href="/typescript/#内置条件类型" class="sidebar-link">内置条件类型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#exclude" class="sidebar-link">Exclude</a></li><li class="sidebar-sub-header"><a href="/typescript/#extract" class="sidebar-link">Extract</a></li><li class="sidebar-sub-header"><a href="/typescript/#nonnullable" class="sidebar-link">NonNullable</a></li><li class="sidebar-sub-header"><a href="/typescript/#returntype" class="sidebar-link">ReturnType</a></li><li class="sidebar-sub-header"><a href="/typescript/#parameters" class="sidebar-link">Parameters</a></li><li class="sidebar-sub-header"><a href="/typescript/#instancetype" class="sidebar-link">InstanceType</a></li><li class="sidebar-sub-header"><a href="/typescript/#infer-分布式" class="sidebar-link">infer+分布式</a></li></ul></li><li><a href="/typescript/#内置工具类型" class="sidebar-link">内置工具类型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#partial" class="sidebar-link">Partial</a></li><li class="sidebar-sub-header"><a href="/typescript/#类型递归" class="sidebar-link">类型递归</a></li><li class="sidebar-sub-header"><a href="/typescript/#required" class="sidebar-link">Required</a></li><li class="sidebar-sub-header"><a href="/typescript/#readonly-2" class="sidebar-link">Readonly</a></li><li class="sidebar-sub-header"><a href="/typescript/#pick" class="sidebar-link">Pick</a></li><li class="sidebar-sub-header"><a href="/typescript/#record" class="sidebar-link">Record</a></li></ul></li><li><a href="/typescript/#自定义高级类型" class="sidebar-link">自定义高级类型</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#proxy" class="sidebar-link">Proxy</a></li><li class="sidebar-sub-header"><a href="/typescript/#setdifference" class="sidebar-link">SetDifference</a></li><li class="sidebar-sub-header"><a href="/typescript/#omit" class="sidebar-link">Omit</a></li><li class="sidebar-sub-header"><a href="/typescript/#diff" class="sidebar-link">Diff</a></li><li class="sidebar-sub-header"><a href="/typescript/#intersection" class="sidebar-link">Intersection</a></li><li class="sidebar-sub-header"><a href="/typescript/#overwrite" class="sidebar-link">Overwrite</a></li><li class="sidebar-sub-header"><a href="/typescript/#merge" class="sidebar-link">Merge</a></li><li class="sidebar-sub-header"><a href="/typescript/#mutable" class="sidebar-link">Mutable</a></li></ul></li><li><a href="/typescript/#模块" class="sidebar-link">模块</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#全局模块" class="sidebar-link">全局模块</a></li><li class="sidebar-sub-header"><a href="/typescript/#文件模块" class="sidebar-link">文件模块</a></li><li class="sidebar-sub-header"><a href="/typescript/#模块规范" class="sidebar-link">模块规范</a></li></ul></li><li><a href="/typescript/#命名空间" class="sidebar-link">命名空间</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#内部划分" class="sidebar-link">内部划分</a></li><li class="sidebar-sub-header"><a href="/typescript/#原理" class="sidebar-link">原理</a></li></ul></li><li><a href="/typescript/#文件、模块与命名空间" class="sidebar-link">文件、模块与命名空间</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/typescript/#类型声明" class="sidebar-link">类型声明</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/typescript/#普通类型声明" class="sidebar-link">普通类型声明</a></li><li class="sidebar-sub-header"><a href="/typescript/#外部枚举" class="sidebar-link">外部枚举</a></li><li class="sidebar-sub-header"><a href="/typescript/#命名空间-2" class="sidebar-link">命名空间</a></li><li class="sidebar-sub-header"><a href="/typescript/#类型声明文件" class="sidebar-link">类型声明文件</a></li><li class="sidebar-sub-header"><a href="/typescript/#第三方声明文件" class="sidebar-link">第三方声明文件</a></li><li class="sidebar-sub-header"><a href="/typescript/#扩展全局变量的类型" class="sidebar-link">扩展全局变量的类型</a></li><li class="sidebar-sub-header"><a href="/typescript/#合并声明" class="sidebar-link">合并声明</a></li><li class="sidebar-sub-header"><a href="/typescript/#类型声明实战" class="sidebar-link">类型声明实战</a></li></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="typescrpit"><a href="#typescrpit" class="header-anchor">#</a> TypeScrpit</h1> <p>既然我们要学习TypeScrpit，首先得知道TypeScrpit是什么，我们为什么要学习它呢？</p> <ul><li>Typescript是由微软开发的一款开源的编程语言</li> <li>Typescript是Javascript的超集，遵循最新的ES5/ES6规范。TypeScript扩展了Javascript语法</li> <li>TypeScript更像后端Java、C#这样的面向对象语言可以让JS开发大型企业应用</li> <li>越来越多的项目是基于TS的，比如VSCode、Angular6、Vue3、React16</li> <li>TS提供的类型系统可以帮助我们在写代码的时候提供更丰富的语法提示</li> <li>在创建前的编译阶段经过类型系统的检查，就可以避免很多线上的错误</li></ul> <h2 id="typescrpit的安装和编译"><a href="#typescrpit的安装和编译" class="header-anchor">#</a> TypeScrpit的安装和编译</h2> <h3 id="安装"><a href="#安装" class="header-anchor">#</a> 安装</h3> <div class="language-js extra-class"><pre class="language-js"><code>cnpm i typescript <span class="token operator">-</span>g
</code></pre></div><p>安装完成后，执行</p> <div class="language-js extra-class"><pre class="language-js"><code>tsc <span class="token number">1.</span>ts
</code></pre></div><h2 id="数据类型"><a href="#数据类型" class="header-anchor">#</a> 数据类型</h2> <p>Typescript是Javascript的超集，所以一般JS支持的数据类型TS都是支持的</p> <h3 id="布尔类型"><a href="#布尔类型" class="header-anchor">#</a> 布尔类型</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> married<span class="token operator">:</span> boolean<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="数字类型-number"><a href="#数字类型-number" class="header-anchor">#</a> 数字类型(number)</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> age<span class="token operator">:</span> number<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="字符串类型-string"><a href="#字符串类型-string" class="header-anchor">#</a> 字符串类型(string)</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> firstname<span class="token operator">:</span> string<span class="token operator">=</span><span class="token string">'zfpx'</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="数组类型-array"><a href="#数组类型-array" class="header-anchor">#</a> 数组类型(array)</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> arr2<span class="token operator">:</span> number<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> arr3<span class="token operator">:</span> Array<span class="token operator">&lt;</span>number<span class="token operator">&gt;=</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>以下为TS新增的数据类型</p> <h3 id="元组类型-tuple"><a href="#元组类型-tuple" class="header-anchor">#</a> 元组类型(tuple)</h3> <p>在 TypeScript 的基础类型中，元组（ Tuple ）表示一个已知数量和类型的数组</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> zhufeng<span class="token operator">:</span><span class="token punctuation">[</span>string<span class="token punctuation">,</span>number<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'zhufeng'</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
zhufeng<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span>
zhufeng<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>数组和元组的区别</p> <table><thead><tr><th>元组</th> <th style="text-align:center;">数组</th></tr></thead> <tbody><tr><td>每一项可以是不同的类型</td> <td style="text-align:center;">每一项都是同一种类型</td></tr> <tr><td>有预定义的长度</td> <td style="text-align:center;">没有长度限制</td></tr> <tr><td>用于表示一个固定的结构</td> <td style="text-align:center;">用于表示一个列表</td></tr></tbody></table> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> animal<span class="token operator">:</span><span class="token punctuation">[</span>string<span class="token punctuation">,</span>number<span class="token punctuation">,</span>boolean<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'zhufeng'</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="枚举类型"><a href="#枚举类型" class="header-anchor">#</a> 枚举类型</h3> <p>事先考虑某一个变量的所有的可能的值，尽量用自然语言中的单词表示它的每一个值，比如性别、月份、星期、颜色、单位、学历</p> <h4 id="普通枚举"><a href="#普通枚举" class="header-anchor">#</a> 普通枚举</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">enum</span> Gender<span class="token punctuation">{</span>
    <span class="token constant">GIRL</span><span class="token punctuation">,</span>
    <span class="token constant">BOY</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">李雷是</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Gender<span class="token punctuation">.</span><span class="token constant">BOY</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">韩梅梅是</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Gender<span class="token punctuation">.</span><span class="token constant">GIRL</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">enum</span> Week<span class="token punctuation">{</span>
    <span class="token constant">MONDAY</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token constant">TUESDAY</span><span class="token operator">=</span><span class="token number">2</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">今天是星期</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Week<span class="token punctuation">.</span><span class="token constant">MONDAY</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="常数枚举"><a href="#常数枚举" class="header-anchor">#</a> 常数枚举</h4> <p>常数枚举与普通枚举的区别是，它会在编译阶段被删除，并且不能包含计算成员。假如包含了计算成员，则会在编译阶段报错</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token keyword">enum</span> Colors <span class="token punctuation">{</span>
    Red<span class="token punctuation">,</span>
    Yellow<span class="token punctuation">,</span>
    Blue
<span class="token punctuation">}</span>

<span class="token keyword">let</span> myColors <span class="token operator">=</span> <span class="token punctuation">[</span>Colors<span class="token punctuation">.</span>Red<span class="token punctuation">,</span> Colors<span class="token punctuation">.</span>Yellow<span class="token punctuation">,</span> Colors<span class="token punctuation">.</span>Blue<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="接口"><a href="#接口" class="header-anchor">#</a> 接口</h2> <ul><li>接口一方面可以在面向对象编程中表示为行为的抽象，另外可以用来描述对象的形状</li> <li>接口就是把一些类中共有的属性和方法抽象出来,可以用来约束实现此接口的类</li> <li>一个类可以继承另一个类并实现多个接口</li> <li>接口像插件一样是用来增强类的，而抽象类是具体类的抽象概念</li> <li>一个类可以实现多个接口，一个接口也可以被多个类实现，但一个类的可以有多个子类，但只能有一个父类</li></ul> <p>interface中可以用分号或者逗号分割每一项，也可以什么都不加</p> <h3 id="对象的形状"><a href="#对象的形状" class="header-anchor">#</a> 对象的形状</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//接口可以用来描述`对象的形状`,少属性或者多属性都会报错</span>
<span class="token keyword">interface</span> <span class="token class-name">Speakable</span><span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
    name<span class="token operator">?</span><span class="token operator">:</span>string<span class="token punctuation">;</span><span class="token comment">//？表示可选属性</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> speakman<span class="token operator">:</span>Speakable <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token comment">//少属性会报错</span>
    name<span class="token punctuation">,</span>
    age<span class="token comment">//多属性也会报错</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="行为的抽象"><a href="#行为的抽象" class="header-anchor">#</a> 行为的抽象</h3> <p>在一个文件中同名的接口可以写多个，类型会自动合并</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//接口可以在面向对象编程中表示为行为的抽象</span>
<span class="token keyword">interface</span> <span class="token class-name">Speakable</span><span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Eatable</span><span class="token punctuation">{</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token comment">//一个类可以实现多个接口</span>
<span class="token keyword">class</span> <span class="token class-name">Person</span>   Speakable<span class="token punctuation">,</span>Eatable<span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Person说话'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">TangDuck</span> <span class="token keyword">implements</span> <span class="token class-name">Speakable</span><span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'TangDuck说话'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="任意属性"><a href="#任意属性" class="header-anchor">#</a> 任意属性</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//无法预先知道有哪些新的属性的时候,可以使用 `[propName:string]:any`,propName名字是任意的</span>
<span class="token keyword">interface</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
  readonly id<span class="token operator">:</span> number<span class="token punctuation">;</span>
  name<span class="token operator">:</span> string<span class="token punctuation">;</span>
  <span class="token punctuation">[</span>propName<span class="token operator">:</span> string<span class="token punctuation">]</span><span class="token operator">:</span> any<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span>
  id<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span>
  name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span><span class="token number">10</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="接口的继承"><a href="#接口的继承" class="header-anchor">#</a> 接口的继承</h3> <p>一个接口可以继承自另外一个接口</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Speakable</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">SpeakChinese</span> <span class="token keyword">extends</span> <span class="token class-name">Speakable</span> <span class="token punctuation">{</span>
    <span class="token function">speakChinese</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token keyword">implements</span> <span class="token class-name">SpeakChinese</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Person'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token function">speakChinese</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'speakChinese'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="readonly"><a href="#readonly" class="header-anchor">#</a> readonly</h3> <p>用 readonly 定义只读属性可以避免由于多人协作或者项目较为复杂等因素造成对象的值被重写</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  readonly id<span class="token operator">:</span>number<span class="token punctuation">;</span>
  name<span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> tom<span class="token operator">:</span>Person <span class="token operator">=</span> <span class="token punctuation">{</span>
  id <span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span>
  name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span>
<span class="token punctuation">}</span>
tom<span class="token punctuation">.</span>id <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="函数类型接口"><a href="#函数类型接口" class="header-anchor">#</a> 函数类型接口</h3> <p>对方法传入的参数和返回值进行约束</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">discount</span><span class="token punctuation">{</span>
  <span class="token punctuation">(</span>price<span class="token operator">:</span>number<span class="token punctuation">)</span><span class="token operator">:</span>number
<span class="token punctuation">}</span>
<span class="token keyword">let</span> cost<span class="token operator">:</span><span class="token function-variable function">discount</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">price<span class="token operator">:</span>number</span><span class="token punctuation">)</span><span class="token operator">:</span>number<span class="token punctuation">{</span>
   <span class="token keyword">return</span> price <span class="token operator">*</span> <span class="token number">.8</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="可索引接口"><a href="#可索引接口" class="header-anchor">#</a> 可索引接口</h3> <ul><li>对数组和对象进行约束</li> <li>userInterface 表示index的类型是 number，那么值的类型必须是 string</li> <li>UserInterface2 表示：index 的类型是 string，那么值的类型必须是 string</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">UserInterface</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>index<span class="token operator">:</span>number<span class="token punctuation">]</span><span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> arr<span class="token operator">:</span>UserInterface <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'zfpx1'</span><span class="token punctuation">,</span><span class="token string">'zfpx2'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">interface</span> <span class="token class-name">UserInterface2</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>index<span class="token operator">:</span>string<span class="token punctuation">]</span><span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> obj<span class="token operator">:</span>UserInterface2 <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="类接口"><a href="#类接口" class="header-anchor">#</a> 类接口</h3> <p>对类的约束</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Speakable</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string<span class="token punctuation">;</span>
    <span class="token function">speak</span><span class="token punctuation">(</span>words<span class="token operator">:</span> string<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">Dog</span> <span class="token keyword">implements</span> <span class="token class-name">Speakable</span> <span class="token punctuation">{</span>
    name<span class="token operator">!</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token parameter">words<span class="token operator">:</span>string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>words<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
dog<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token string">'汪汪汪'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="构造函数的类型"><a href="#构造函数的类型" class="header-anchor">#</a> 构造函数的类型</h3> <ul><li>在 TypeScript 中，我们可以用 interface 来描述类</li> <li>同时也可以使用interface里特殊的new()关键字来描述类的构造函数类型</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">Animal</span><span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">public</span> name<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//不加new是修饰函数的,加new是修饰类的</span>
<span class="token keyword">interface</span> <span class="token class-name">WithNameClass</span><span class="token punctuation">{</span>
  <span class="token keyword">new</span><span class="token punctuation">(</span>name<span class="token operator">:</span>string<span class="token punctuation">)</span><span class="token operator">:</span>Animal
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">createAnimal</span><span class="token punctuation">(</span><span class="token parameter">clazz<span class="token operator">:</span>WithNameClass<span class="token punctuation">,</span>name<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
   <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">clazz</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token function">createAnimal</span><span class="token punctuation">(</span>Animal<span class="token punctuation">,</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="抽象类-vs-接口"><a href="#抽象类-vs-接口" class="header-anchor">#</a> 抽象类 vs 接口</h3> <ul><li>不同类之间公有的属性或方法，可以抽象成一个接口（Interfaces）</li> <li>而抽象类是供其他类继承的基类，抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现</li> <li>抽象类本质是一个无法被实例化的类，其中能够实现方法和初始化属性，而接口仅能够用于描述,既不提供方法的实现，也不为属性进行初始化</li> <li>一个类可以继承一个类或抽象类，但可以实现（implements）多个接口</li> <li>抽象类也可以实现接口</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>abstract <span class="token keyword">class</span> <span class="token class-name">Animal</span><span class="token punctuation">{</span>
    name<span class="token operator">:</span>string<span class="token punctuation">;</span>
    <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    abstract <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Flying</span><span class="token punctuation">{</span>
      <span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">Duck</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token keyword">implements</span> <span class="token class-name">Flying</span><span class="token punctuation">{</span>
      <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
          console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'汪汪汪'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
          console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'我会飞'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> duck <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Duck</span><span class="token punctuation">(</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
duck<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
duck<span class="token punctuation">.</span><span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Type1</span> <span class="token punctuation">{</span>
  <span class="token comment">// 修饰的方法</span>
  <span class="token punctuation">(</span>name<span class="token operator">:</span>string<span class="token punctuation">)</span><span class="token operator">:</span>any
<span class="token punctuation">}</span>

<span class="token keyword">interface</span> <span class="token class-name">Type2</span> <span class="token punctuation">{</span>
  <span class="token comment">// 修饰对象的属性a的值</span>
  <span class="token function-variable function">a</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span>any
<span class="token punctuation">}</span>

<span class="token keyword">let</span> t1<span class="token operator">:</span> <span class="token function-variable function">Type1</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token operator">:</span>string</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">let</span> t2<span class="token operator">:</span> Type2 <span class="token operator">=</span> <span class="token punctuation">{</span>
  a<span class="token operator">:</span> t1
<span class="token punctuation">}</span>
</code></pre></div><h2 id="泛型接口"><a href="#泛型接口" class="header-anchor">#</a> 泛型接口</h2> <p>泛型接口可以用来约束函数</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 泛型接口知识点1</span>
<span class="token keyword">interface</span> <span class="token class-name">Calculate</span><span class="token punctuation">{</span>
  <span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>a<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">,</span>b<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">T</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> add<span class="token operator">:</span><span class="token function-variable function">Calculate</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>a<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">,</span>b<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">{</span>
  <span class="token keyword">return</span> a <span class="token punctuation">;</span> 
<span class="token punctuation">}</span>
add<span class="token operator">&lt;</span>number<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token comment">// 泛型接口知识点2</span>
<span class="token keyword">interface</span> <span class="token class-name">Calculate</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>
  <span class="token punctuation">(</span>a<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">,</span>b<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">T</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> add<span class="token operator">:</span>Calculate<span class="token operator">&lt;</span>number<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">:</span>number<span class="token punctuation">,</span>b<span class="token operator">:</span>number</span><span class="token punctuation">)</span><span class="token operator">:</span>number<span class="token punctuation">{</span>
  <span class="token keyword">return</span> a <span class="token punctuation">;</span> 
<span class="token punctuation">}</span>
<span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 泛型接口知识点3</span>
<span class="token keyword">interface</span> <span class="token class-name">Calculate</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>
  <span class="token operator">&lt;</span><span class="token constant">U</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>a<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">,</span>b<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">U</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> add<span class="token operator">:</span>Calculate<span class="token operator">&lt;</span>number<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token operator">&lt;</span><span class="token constant">U</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>a<span class="token operator">:</span>number<span class="token punctuation">,</span>b<span class="token operator">:</span>number<span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">U</span><span class="token punctuation">{</span>
  <span class="token keyword">return</span> a <span class="token keyword">as</span> any<span class="token punctuation">;</span> 
<span class="token punctuation">}</span>
add<span class="token operator">&lt;</span>number<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre></div><h1 id="类型保护"><a href="#类型保护" class="header-anchor">#</a> 类型保护</h1> <ul><li>类型保护就是一些表达式，他们在编译的时候就能通过类型信息确保某个作用域内变量的类型</li> <li>类型保护就是能够通过关键字判断出分支中的类型</li></ul> <h2 id="typeof-类型保护"><a href="#typeof-类型保护" class="header-anchor">#</a> typeof 类型保护</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">double</span><span class="token punctuation">(</span><span class="token parameter">input<span class="token operator">:</span> string <span class="token operator">|</span> number <span class="token operator">|</span> boolean</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> input <span class="token operator">===</span> <span class="token string">'string'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> input <span class="token operator">+</span> input<span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> input <span class="token operator">===</span> <span class="token string">'number'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> input <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token operator">!</span>input<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="instanceof类型保护"><a href="#instanceof类型保护" class="header-anchor">#</a> instanceof类型保护</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span>
    name<span class="token operator">!</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">Bird</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span>
    swing<span class="token operator">!</span><span class="token operator">:</span> number
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token parameter">animal<span class="token operator">:</span> Animal</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>animal <span class="token keyword">instanceof</span> <span class="token class-name">Bird</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>animal<span class="token punctuation">.</span>swing<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>animal<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="null保护"><a href="#null保护" class="header-anchor">#</a> null保护</h2> <p>如果开启了strictNullChecks选项，那么对于可能为null的变量不能调用它上面的方法和属性</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">getFirstLetter</span><span class="token punctuation">(</span><span class="token parameter">s<span class="token operator">:</span> string <span class="token operator">|</span> <span class="token keyword">null</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//第一种方式是加上null判断</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>s <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">''</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//第二种处理是增加一个或的处理</span>
    s <span class="token operator">=</span> s <span class="token operator">||</span> <span class="token string">''</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> s<span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//它并不能处理一些复杂的判断，需要加非空断言操作符</span>
<span class="token keyword">function</span> <span class="token function">getFirstLetter2</span><span class="token punctuation">(</span><span class="token parameter">s<span class="token operator">:</span> string <span class="token operator">|</span> <span class="token keyword">null</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">function</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s<span class="token operator">!</span><span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    s <span class="token operator">=</span> s <span class="token operator">||</span> <span class="token string">''</span><span class="token punctuation">;</span>
    <span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> s<span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="链判断运算符"><a href="#链判断运算符" class="header-anchor">#</a> 链判断运算符</h2> <ul><li>链判断运算符是一种先检查属性是否存在，再尝试访问该属性的运算符，其符号为 ?.</li> <li>如果运算符左侧的操作数 ?. 计算为 undefined 或 null，则表达式求值为 undefined 。否则，正常触发目标属性访问，方法或函数调用。</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>a<span class="token operator">?.</span>b<span class="token punctuation">;</span> <span class="token comment">//如果a是null/undefined,那么返回undefined，否则返回a.b的值.</span>
a <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">undefined</span> <span class="token operator">:</span> a<span class="token punctuation">.</span>b<span class="token punctuation">;</span>

a<span class="token operator">?.</span><span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//如果a是null/undefined,那么返回undefined，否则返回a[x]的值</span>
a <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">undefined</span> <span class="token operator">:</span> a<span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">;</span>

a<span class="token operator">?.</span><span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 如果a是null/undefined,那么返回undefined</span>
a <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">undefined</span> <span class="token operator">:</span> a<span class="token punctuation">.</span><span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//如果a.b不函数的话抛类型错误异常,否则计算a.b()的结果</span>

a<span class="token operator">?.</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//如果a是null/undefined,那么返回undefined</span>
a <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">undefined</span> <span class="token operator">:</span> <span class="token function">a</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//如果A不是函数会抛出类型错误</span>
<span class="token comment">//否则 调用a这个函数</span>
</code></pre></div><p>链判断运算符 还处于 stage1 阶段,TS 也暂时不支持</p> <h2 id="可辨识的联合类型"><a href="#可辨识的联合类型" class="header-anchor">#</a> 可辨识的联合类型</h2> <ul><li>就是利用联合类型中的共有字段进行类型保护的一种技巧</li> <li>相同字段的不同取值就是可辨识</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">WarningButton</span><span class="token punctuation">{</span>
  <span class="token keyword">class</span><span class="token operator">:</span><span class="token string">'warning'</span><span class="token punctuation">,</span>
  text1<span class="token operator">:</span><span class="token string">'修改'</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">DangerButton</span><span class="token punctuation">{</span>
  <span class="token keyword">class</span><span class="token operator">:</span><span class="token string">'danger'</span><span class="token punctuation">,</span>
  text2<span class="token operator">:</span><span class="token string">'删除'</span>
<span class="token punctuation">}</span>
type Button <span class="token operator">=</span> WarningButton<span class="token operator">|</span>DangerButton<span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">getButton</span><span class="token punctuation">(</span><span class="token parameter">button<span class="token operator">:</span>Button</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
 <span class="token keyword">if</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>class<span class="token operator">==</span><span class="token string">'warning'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>text1<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token punctuation">}</span>
 <span class="token keyword">if</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>class<span class="token operator">==</span><span class="token string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>text2<span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>类型字面量+可辨识联合类型</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    username<span class="token operator">:</span> string
<span class="token punctuation">}</span>
type Action <span class="token operator">=</span> <span class="token punctuation">{</span>
    type<span class="token operator">:</span><span class="token string">'add'</span><span class="token punctuation">,</span>
    payload<span class="token operator">:</span>User
<span class="token punctuation">}</span> <span class="token operator">|</span> <span class="token punctuation">{</span>
    type<span class="token operator">:</span> <span class="token string">'delete'</span>
    payload<span class="token operator">:</span> number
<span class="token punctuation">}</span>
<span class="token keyword">const</span> <span class="token function-variable function">UserReducer</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">action<span class="token operator">:</span> Action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">switch</span> <span class="token punctuation">(</span>action<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">case</span> <span class="token string">&quot;add&quot;</span><span class="token operator">:</span>
      <span class="token keyword">let</span> user<span class="token operator">:</span> User <span class="token operator">=</span> action<span class="token punctuation">.</span>payload<span class="token punctuation">;</span>
      <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> <span class="token string">&quot;delete&quot;</span><span class="token operator">:</span>
      <span class="token keyword">let</span> id<span class="token operator">:</span> number <span class="token operator">=</span> action<span class="token punctuation">.</span>payload<span class="token punctuation">;</span>
      <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">default</span><span class="token operator">:</span>
      <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="in操作符"><a href="#in操作符" class="header-anchor">#</a> in操作符</h2> <p>in 运算符可以被用于参数类型的判断</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Bird</span> <span class="token punctuation">{</span>
    swing<span class="token operator">:</span> number<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">interface</span> <span class="token class-name">Dog</span> <span class="token punctuation">{</span>
    leg<span class="token operator">:</span> number<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">getNumber</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> Bird <span class="token operator">|</span> Dog</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">&quot;swing&quot;</span> <span class="token keyword">in</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> x<span class="token punctuation">.</span>swing<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> x<span class="token punctuation">.</span>leg<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="自定义的类型保护"><a href="#自定义的类型保护" class="header-anchor">#</a> 自定义的类型保护</h2> <ul><li>TypeScript 里的类型保护本质上就是一些表达式，它们会在运行时检查类型信息，以确保在某个作用域里的类型是符合预期的</li> <li>type is Type1Class就是类型谓词</li> <li>谓词为 parameterName is Type这种形式,parameterName必须是来自于当前函数签名里的一个参数名</li> <li>每当使用一些变量调用isType1时，如果原始类型兼容，TypeScript会将该变量缩小到该特定类型
形式</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">isType1</span><span class="token punctuation">(</span><span class="token parameter">type<span class="token operator">:</span> Type1Class <span class="token operator">|</span> Type2Class</span><span class="token punctuation">)</span><span class="token operator">:</span> type is Type1Class <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator">&lt;</span>Type1Class<span class="token operator">&gt;</span>type<span class="token punctuation">)</span><span class="token punctuation">.</span>func1 <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>实例代码</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Bird</span> <span class="token punctuation">{</span>
  swing<span class="token operator">:</span> number<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">interface</span> <span class="token class-name">Dog</span> <span class="token punctuation">{</span>
  leg<span class="token operator">:</span> number<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//没有相同字段可以定义一个类型保护函数</span>
<span class="token keyword">function</span> <span class="token function">isBird</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span>Bird<span class="token operator">|</span>Dog</span><span class="token punctuation">)</span><span class="token operator">:</span> x is Bird<span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator">&lt;</span>Bird<span class="token operator">&gt;</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span>swing <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">;</span>
  <span class="token comment">//return (x as Bird).swing == 2;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">getAnimal</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> Bird <span class="token operator">|</span> Dog</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isBird</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> x<span class="token punctuation">.</span>swing<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> x<span class="token punctuation">.</span>leg<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="unknown"><a href="#unknown" class="header-anchor">#</a> unknown</h2> <ul><li>TypeScript 3.0 引入了新的unknown 类型，它是 any 类型对应的安全类型</li> <li>unknown 和 any 的主要区别是 unknown 类型会更加严格：在对 unknown 类型的值执行大多数操作之前，我们 必须进行某种形式的检查。而在对 any 类型的值执行操作之前，我们不必进行任何检查</li></ul> <h3 id="any-类型"><a href="#any-类型" class="header-anchor">#</a> any 类型</h3> <ul><li>在 TypeScript 中，任何类型都可以被归为 any 类型。这让 any 类型成为了类型系统的 顶级类型 (也被称作 全局超级类型)。</li> <li>TypeScript允许我们对 any 类型的值执行任何操作，而无需事先执行任何形式的检查</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> value<span class="token operator">:</span> any<span class="token punctuation">;</span>

value <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>             <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token string">&quot;Hello World&quot;</span><span class="token punctuation">;</span>    <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> Math<span class="token punctuation">.</span>random<span class="token punctuation">;</span>      <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>             <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>        <span class="token comment">// OK</span>


<span class="token keyword">let</span> value<span class="token operator">:</span> any<span class="token punctuation">;</span>
value<span class="token punctuation">.</span>foo<span class="token punctuation">.</span>bar<span class="token punctuation">;</span>  <span class="token comment">// OK</span>
value<span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// OK</span>
<span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// OK</span>
<span class="token keyword">new</span> <span class="token class-name">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// OK</span>
</code></pre></div><h3 id="unknown-类型"><a href="#unknown-类型" class="header-anchor">#</a> unknown 类型</h3> <ul><li>就像所有类型都可以被归为 any，所有类型也都可以被归为 unknown。这使得 unknown 成为 TypeScript 类型系统的另一种顶级类型（另一种是 any）</li> <li>任何类型都可以赋值给unknown类型</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> value<span class="token operator">:</span> unknown<span class="token punctuation">;</span>

value <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>             <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token string">&quot;Hello World&quot;</span><span class="token punctuation">;</span>    <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>               <span class="token comment">// OK</span>
value <span class="token operator">=</span> Math<span class="token punctuation">.</span>random<span class="token punctuation">;</span>      <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>             <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>        <span class="token comment">// OK</span>
value <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// OK</span>
</code></pre></div><ul><li>unknown类型只能被赋值给any类型和unknown类型本身</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> value<span class="token operator">:</span> unknown<span class="token punctuation">;</span>
<span class="token keyword">let</span> value1<span class="token operator">:</span> unknown <span class="token operator">=</span> value<span class="token punctuation">;</span>   <span class="token comment">// OK</span>
<span class="token keyword">let</span> value2<span class="token operator">:</span> any <span class="token operator">=</span> value<span class="token punctuation">;</span>       <span class="token comment">// OK</span>
<span class="token keyword">let</span> value3<span class="token operator">:</span> boolean <span class="token operator">=</span> value<span class="token punctuation">;</span>   <span class="token comment">// Error</span>
<span class="token keyword">let</span> value4<span class="token operator">:</span> number <span class="token operator">=</span> value<span class="token punctuation">;</span>    <span class="token comment">// Error</span>
<span class="token keyword">let</span> value5<span class="token operator">:</span> string <span class="token operator">=</span> value<span class="token punctuation">;</span>    <span class="token comment">// Error</span>
<span class="token keyword">let</span> value6<span class="token operator">:</span> object <span class="token operator">=</span> value<span class="token punctuation">;</span>    <span class="token comment">// Error</span>
<span class="token keyword">let</span> value7<span class="token operator">:</span> any<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>     <span class="token comment">// Error</span>
<span class="token keyword">let</span> value8<span class="token operator">:</span> Function <span class="token operator">=</span> value<span class="token punctuation">;</span>  <span class="token comment">// Error</span>
</code></pre></div><h3 id="缩小-unknown-类型范围"><a href="#缩小-unknown-类型范围" class="header-anchor">#</a> 缩小 unknown 类型范围</h3> <ul><li>如果没有类型断言或类型细化时，不能在unknown上面进行任何操作</li> <li>typeof</li> <li>instanceof</li> <li>自定义类型保护函数</li> <li>可以对 unknown 类型使用类型断言</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> value<span class="token operator">:</span> unknown <span class="token operator">=</span> <span class="token string">&quot;Hello World&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> someString<span class="token operator">:</span> string <span class="token operator">=</span> value <span class="token keyword">as</span> string<span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> value <span class="token operator">===</span> <span class="token string">'string'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">.</span>length<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="联合类型中的-unknown-类型"><a href="#联合类型中的-unknown-类型" class="header-anchor">#</a> 联合类型中的 unknown 类型</h3> <p>在联合类型中，unknown 类型会吸收任何类型。这就意味着如果任一组成类型是 unknown，联合类型也会相当于 unknown：</p> <div class="language-js extra-class"><pre class="language-js"><code>type UnionType1 <span class="token operator">=</span> unknown <span class="token operator">|</span> <span class="token keyword">null</span><span class="token punctuation">;</span>       <span class="token comment">// unknown</span>
type UnionType2 <span class="token operator">=</span> unknown <span class="token operator">|</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>  <span class="token comment">// unknown</span>
type UnionType3 <span class="token operator">=</span> unknown <span class="token operator">|</span> string<span class="token punctuation">;</span>     <span class="token comment">// unknown</span>
type UnionType4 <span class="token operator">=</span> unknown <span class="token operator">|</span> number<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>   <span class="token comment">// unknown</span>
</code></pre></div><h3 id="交叉类型中的-unknown-类型"><a href="#交叉类型中的-unknown-类型" class="header-anchor">#</a> 交叉类型中的 unknown 类型</h3> <p>在交叉类型中，任何类型都可以吸收 unknown 类型。这意味着将任何类型与 unknown 相交不会改变结果类型</p> <div class="language-js extra-class"><pre class="language-js"><code>type IntersectionType1 <span class="token operator">=</span> unknown <span class="token operator">&amp;</span> <span class="token keyword">null</span><span class="token punctuation">;</span>       <span class="token comment">// null</span>
type IntersectionType2 <span class="token operator">=</span> unknown <span class="token operator">&amp;</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>  <span class="token comment">// undefined</span>
type IntersectionType3 <span class="token operator">=</span> unknown <span class="token operator">&amp;</span> string<span class="token punctuation">;</span>     <span class="token comment">// string</span>
type IntersectionType4 <span class="token operator">=</span> unknown <span class="token operator">&amp;</span> number<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>   <span class="token comment">// number[]</span>
type IntersectionType5 <span class="token operator">=</span> unknown <span class="token operator">&amp;</span> any<span class="token punctuation">;</span>        <span class="token comment">// any</span>

<span class="token keyword">interface</span> <span class="token class-name">A</span><span class="token punctuation">{</span>name<span class="token operator">:</span>string<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">B</span><span class="token punctuation">{</span>age<span class="token operator">:</span>number<span class="token punctuation">}</span>
type <span class="token constant">C</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token operator">&amp;</span> <span class="token constant">B</span>
<span class="token keyword">let</span> c<span class="token operator">:</span><span class="token constant">C</span><span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">''</span><span class="token punctuation">,</span> age<span class="token operator">:</span><span class="token number">18</span><span class="token punctuation">}</span>
type <span class="token constant">AA</span> <span class="token operator">=</span> string<span class="token operator">|</span>number
type <span class="token constant">BB</span> <span class="token operator">=</span> string<span class="token operator">|</span>boolean
type <span class="token constant">CC</span> <span class="token operator">=</span> <span class="token constant">AA</span> <span class="token operator">&amp;</span> <span class="token constant">BB</span>
</code></pre></div><p>unknown跟赋不赋值没有关系</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> val<span class="token operator">:</span>unknown
val <span class="token operator">=</span> <span class="token number">1</span>
</code></pre></div><p>虽然给val赋值为1了，但是val还是unknown类型</p> <h3 id="never是unknown的子类型"><a href="#never是unknown的子类型" class="header-anchor">#</a> never是unknown的子类型</h3> <div class="language-js extra-class"><pre class="language-js"><code>type isNever <span class="token operator">=</span> never <span class="token keyword">extends</span> <span class="token class-name">unknown</span> <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="keyof-unknown-等于never"><a href="#keyof-unknown-等于never" class="header-anchor">#</a> keyof unknown 等于never</h3> <div class="language-js extra-class"><pre class="language-js"><code>type keys <span class="token operator">=</span> keyof unknown
</code></pre></div><h3 id="只能对unknown进行等或不等操作-不能进行其它操作"><a href="#只能对unknown进行等或不等操作-不能进行其它操作" class="header-anchor">#</a> 只能对unknown进行等或不等操作，不能进行其它操作</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> un1<span class="token operator">:</span>unknown
<span class="token keyword">let</span> un2<span class="token operator">:</span>unknown
un1<span class="token operator">===</span>un2<span class="token punctuation">;</span>
un1<span class="token operator">!==</span>un2<span class="token punctuation">;</span>
un1 <span class="token operator">+=</span> un2<span class="token punctuation">;</span> <span class="token comment">//报错</span>
</code></pre></div><h3 id="不能做任何操作"><a href="#不能做任何操作" class="header-anchor">#</a> 不能做任何操作</h3> <ul><li>不能访问属性</li> <li>不能作为函数调用</li> <li>不能当作类的构造函数不能创建实例</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>un<span class="token punctuation">.</span>name
<span class="token function">un</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">new</span> <span class="token class-name">un</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="映射属性"><a href="#映射属性" class="header-anchor">#</a> 映射属性</h3> <p>如果映射类型遍历的时候是unknown,不会映射属性</p> <div class="language-js extra-class"><pre class="language-js"><code>type getType<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span>number
<span class="token punctuation">}</span>
type t <span class="token operator">=</span> getType<span class="token operator">&lt;</span>unknown<span class="token operator">&gt;</span><span class="token punctuation">;</span>
</code></pre></div><h1 id="类型变换"><a href="#类型变换" class="header-anchor">#</a> 类型变换</h1> <h2 id="类型推断"><a href="#类型推断" class="header-anchor">#</a> 类型推断</h2> <p>TypeScript 能根据一些简单的规则推断变量的类型</p> <h3 id="从右向左"><a href="#从右向左" class="header-anchor">#</a> 从右向左</h3> <ul><li>变量的类型可以由定义推断</li> <li>这是一个从右向左流动类型的示例</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 从赋值中推断出来的</span>
<span class="token keyword">let</span> foo <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// foo 是 'number'</span>
<span class="token keyword">let</span> bar <span class="token operator">=</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">;</span> <span class="token comment">// bar 是 'string'</span>
<span class="token comment">//foo = bar; // Error: 不能将 'string' 赋值给 `number`</span>
</code></pre></div><h3 id="底部流出"><a href="#底部流出" class="header-anchor">#</a> 底部流出</h3> <p>返回类型能被 return 语句推断</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">:</span> number<span class="token punctuation">,</span> b<span class="token operator">:</span> number</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="从左向右"><a href="#从左向右" class="header-anchor">#</a> 从左向右</h3> <p>函数参数类型/返回值类型也能通过赋值来推断</p> <div class="language-js extra-class"><pre class="language-js"><code>type <span class="token function-variable function">Sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">:</span> number<span class="token punctuation">,</span> b<span class="token operator">:</span> number</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> number<span class="token punctuation">;</span>
<span class="token keyword">let</span> sum<span class="token operator">:</span> <span class="token function-variable function">Sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    a<span class="token operator">=</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="结构化"><a href="#结构化" class="header-anchor">#</a> 结构化</h3> <p>推断规则也适用于结构化的存在(对象字面量)</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span> <span class="token number">11</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> name <span class="token operator">=</span>person<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
<span class="token keyword">let</span> age <span class="token operator">=</span>person<span class="token punctuation">.</span>age<span class="token punctuation">;</span>
age <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span> <span class="token comment">// Error：不能把 'string' 类型赋值给 'number' 类型</span>
</code></pre></div><h3 id="解构"><a href="#解构" class="header-anchor">#</a> 解构</h3> <p>推断规则也适用于解构</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span> <span class="token number">11</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span>age <span class="token punctuation">}</span> <span class="token operator">=</span> person<span class="token punctuation">;</span>

age <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span> <span class="token comment">// Error：不能把 'string' 类型赋值给 'number' 类型</span>

<span class="token comment">//数组也一样</span>
<span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
numbers<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span> <span class="token comment">// Error：不能把 'string' 类型赋值给 'number' 类型</span>
</code></pre></div><h3 id="defaultprops"><a href="#defaultprops" class="header-anchor">#</a> DefaultProps</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">DefaultProps</span><span class="token punctuation">{</span>
  <span class="token comment">// ? name、age可选</span>
    name<span class="token operator">?</span><span class="token operator">:</span>string<span class="token punctuation">;</span>
    age<span class="token operator">?</span><span class="token operator">:</span>number<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> defaultProps<span class="token operator">:</span> DefaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// 如果有DefaultProps下面的props中的name、age也是可选的，如果没有DefaultProps，那么name、age是必填的</span>
  <span class="token comment">//  name:'fangfeiyue',</span>
  <span class="token comment">//  age:10</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> props <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token operator">...</span>defaultProps<span class="token punctuation">,</span>
    home<span class="token operator">:</span><span class="token string">'北京'</span>
<span class="token punctuation">}</span>
type Props <span class="token operator">=</span> <span class="token keyword">typeof</span> props<span class="token punctuation">;</span>
</code></pre></div><h3 id="小心使用返回值"><a href="#小心使用返回值" class="header-anchor">#</a> 小心使用返回值</h3> <p>尽管 TypeScript 一般情况下能推断函数的返回值，但是它可能并不是你想要的</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">addOne</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">:</span>any</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token operator">:</span> number<span class="token punctuation">,</span> b<span class="token operator">:</span> number</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// return a + addOne(b); 这样会报错，因为number加any类型还是any类型，如果强转的下的话是可以的</span>
    <span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token function">addOne</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token keyword">as</span> number
<span class="token punctuation">}</span>
</code></pre></div><h2 id="交叉类型"><a href="#交叉类型" class="header-anchor">#</a> 交叉类型</h2> <ul><li>交叉类型(Intersection Types)是将多个类型合并为一个类型</li> <li>这让我们可以把现有的多种类型叠加到一起成为一种类型，它包含了所需的所有类型的特性</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//TypeScript 交叉类型是将多个类型合并为一个类型</span>
<span class="token comment">//这让我们可以把现有的多种类型叠加到一起成为一种类型</span>
<span class="token comment">//它包含了所需的所有类型的特性</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">//接口的交叉</span>
<span class="token keyword">interface</span> <span class="token class-name">Bird</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string<span class="token punctuation">,</span>
    <span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string<span class="token punctuation">,</span>
    <span class="token function">talk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span>
<span class="token punctuation">}</span>
type BirdPerson <span class="token operator">=</span> Bird <span class="token operator">&amp;</span> Person<span class="token punctuation">;</span>
<span class="token keyword">let</span> p<span class="token operator">:</span> BirdPerson <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span> <span class="token function">fly</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">talk</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
p<span class="token punctuation">.</span>fly<span class="token punctuation">;</span>
p<span class="token punctuation">.</span>name
p<span class="token punctuation">.</span>talk<span class="token punctuation">;</span>


<span class="token keyword">interface</span> <span class="token class-name">X</span> <span class="token punctuation">{</span>
    a<span class="token operator">:</span> string<span class="token punctuation">;</span>
    b<span class="token operator">:</span> string<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">interface</span> <span class="token class-name">Y</span> <span class="token punctuation">{</span>
    a<span class="token operator">:</span> number<span class="token punctuation">;</span>
    c<span class="token operator">:</span> string
<span class="token punctuation">}</span>

type <span class="token constant">XY</span> <span class="token operator">=</span> <span class="token constant">X</span> <span class="token operator">&amp;</span> <span class="token constant">Y</span><span class="token punctuation">;</span>
type <span class="token constant">YX</span> <span class="token operator">=</span> <span class="token constant">Y</span> <span class="token operator">&amp;</span> <span class="token constant">X</span><span class="token punctuation">;</span>
<span class="token comment">//c = string &amp; number</span>
<span class="token comment">//let p1: XY={a:'',b:'',c:''};</span>
</code></pre></div><p>联合类型的交叉类型</p> <div class="language-js extra-class"><pre class="language-js"><code>type Ta <span class="token operator">=</span> string <span class="token operator">|</span> number<span class="token punctuation">;</span>
type Tb <span class="token operator">=</span> number <span class="token operator">|</span> boolean<span class="token punctuation">;</span>
type Tc <span class="token operator">=</span> Ta <span class="token operator">&amp;</span> Tb<span class="token punctuation">;</span>
</code></pre></div><p>mixin混入模式可以让你从两个对象中创建一个新对象，新对象会拥有着两个对象所有的功能</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">AnyObject</span> <span class="token punctuation">{</span>
    <span class="token punctuation">[</span>prop<span class="token operator">:</span> string<span class="token punctuation">]</span><span class="token operator">:</span> any<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> mixin<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">AnyObject</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">AnyObject</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>one<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">,</span>two<span class="token operator">:</span> <span class="token constant">U</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span> <span class="token operator">&amp;</span> <span class="token constant">U</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token operator">&amp;</span> <span class="token constant">U</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> one<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token punctuation">(</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span>result<span class="token punctuation">)</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> one<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> two<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token punctuation">(</span><span class="token operator">&lt;</span><span class="token constant">U</span><span class="token operator">&gt;</span>result<span class="token punctuation">)</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> two<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token function">mixin</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">&quot;fangfeiyue&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> age<span class="token operator">:</span> <span class="token number">11</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">.</span>name<span class="token punctuation">,</span> x<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="typeof"><a href="#typeof" class="header-anchor">#</a> typeof</h2> <p>可以获取一个变量的类型</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//先定义类型，再定义变量</span>
type People <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span>string<span class="token punctuation">,</span>
    age<span class="token operator">:</span>number<span class="token punctuation">,</span>
    gender<span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> p1<span class="token operator">:</span>People <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>
    gender<span class="token operator">:</span><span class="token string">'male'</span>
<span class="token punctuation">}</span>

<span class="token comment">//先定义变量，再定义类型</span>
<span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>
    gender<span class="token operator">:</span><span class="token string">'male'</span>
<span class="token punctuation">}</span>
type People <span class="token operator">=</span> <span class="token keyword">typeof</span> p1<span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token parameter">p<span class="token operator">:</span>People</span><span class="token punctuation">)</span><span class="token operator">:</span>string<span class="token punctuation">{</span>
    <span class="token keyword">return</span> p<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">getName</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="索引访问操作符"><a href="#索引访问操作符" class="header-anchor">#</a> 索引访问操作符</h2> <p>可以通过[]获取一个类型的子类型</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
    name<span class="token operator">:</span>string<span class="token punctuation">;</span>
    age<span class="token operator">:</span>number<span class="token punctuation">;</span>
    job<span class="token operator">:</span><span class="token punctuation">{</span>
        name<span class="token operator">:</span>string
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    interests<span class="token operator">:</span><span class="token punctuation">{</span>name<span class="token operator">:</span>string<span class="token punctuation">,</span>level<span class="token operator">:</span>number<span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> FrontEndJob<span class="token operator">:</span>Person<span class="token punctuation">[</span><span class="token string">'job'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token string">'前端工程师'</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> interestLevel<span class="token operator">:</span>Person<span class="token punctuation">[</span><span class="token string">'interests'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">'level'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="keyof"><a href="#keyof" class="header-anchor">#</a> keyof</h2> <p>索引类型查询操作符</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span>number<span class="token punctuation">;</span>
  gender<span class="token operator">:</span><span class="token string">'male'</span><span class="token operator">|</span><span class="token string">'female'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//type PersonKey = 'name'|'age'|'gender';</span>
type PersonKey <span class="token operator">=</span> keyof Person<span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">getValueByKey</span><span class="token punctuation">(</span><span class="token parameter">p<span class="token operator">:</span>Person<span class="token punctuation">,</span>key<span class="token operator">:</span>PersonKey</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">return</span> p<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token function">getValueByKey</span><span class="token punctuation">(</span><span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>gender<span class="token operator">:</span><span class="token string">'male'</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="映射类型"><a href="#映射类型" class="header-anchor">#</a> 映射类型</h2> <p>在定义的时候用in操作符去批量定义类型中的属性</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span>number<span class="token punctuation">;</span>
  gender<span class="token operator">:</span><span class="token string">'male'</span><span class="token operator">|</span><span class="token string">'female'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//批量把一个接口中的属性都变成可选的</span>
type PartPerson <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>Key <span class="token keyword">in</span> keyof Person<span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span>Person<span class="token punctuation">[</span>Key<span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> p1<span class="token operator">:</span>PartPerson<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">//也可以使用泛型</span>
type Part<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>key <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> p2<span class="token operator">:</span>Part<span class="token operator">&lt;</span>Person<span class="token operator">&gt;=</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

type k <span class="token operator">=</span> keyof Person <span class="token comment">// name, age, gender 是一个接口属性名的联合类型 </span>
</code></pre></div><p>通过key的数组获取值的数组</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token class-name">keyof</span> <span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>o<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">,</span> names<span class="token operator">:</span> <span class="token constant">K</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> names<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> o<span class="token punctuation">[</span>n<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
type User <span class="token operator">=</span> <span class="token keyword">typeof</span> user<span class="token punctuation">;</span>
<span class="token keyword">const</span> res <span class="token operator">=</span> pick<span class="token operator">&lt;</span>User<span class="token punctuation">,</span> keyof User<span class="token operator">&gt;</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>interface和type的区别</p> <p>别名不会创建一个类型，它只会创建一个新的名字来引用现有类型，所以叫做类型别名，类型别名也无法被继承</p> <h2 id="条件类型"><a href="#条件类型" class="header-anchor">#</a> 条件类型</h2> <p>在定义泛型的时候能够添加进逻辑分支，以定义更加灵活的泛型</p> <h3 id="定义条件类型"><a href="#定义条件类型" class="header-anchor">#</a> 定义条件类型</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Fish</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Water</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Bird</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Sky</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token comment">//若 T 能够赋值给 Fish，那么类型是 Water,否则为 Sky</span>
type Condition<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">Fish</span> <span class="token operator">?</span> Water <span class="token operator">:</span> Sky<span class="token punctuation">;</span>
<span class="token keyword">let</span> condition<span class="token operator">:</span> Condition<span class="token operator">&lt;</span>Fish<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>  <span class="token operator">:</span> <span class="token string">'水'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> 
</code></pre></div><h3 id="条件类型的分发"><a href="#条件类型的分发" class="header-anchor">#</a> 条件类型的分发</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Fish</span> <span class="token punctuation">{</span>
    fish<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Water</span> <span class="token punctuation">{</span>
    water<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Bird</span> <span class="token punctuation">{</span>
    bird<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Sky</span> <span class="token punctuation">{</span>
    sky<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token comment">//naked type</span>
type Condition<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">Fish</span> <span class="token operator">?</span> Water <span class="token operator">:</span> Sky<span class="token punctuation">;</span>

<span class="token comment">//(Fish extends Fish ? Water : Sky) | (Bird extends Fish ? Water : Sky)</span>
<span class="token comment">// Water|Sky</span>
<span class="token keyword">let</span> condition1<span class="token operator">:</span> Condition<span class="token operator">&lt;</span>Fish <span class="token operator">|</span> Bird<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> water<span class="token operator">:</span> <span class="token string">'水'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> condition2<span class="token operator">:</span> Condition<span class="token operator">&lt;</span>Fish <span class="token operator">|</span> Bird<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> sky<span class="token operator">:</span> <span class="token string">'天空'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>条件类型有一个特性,就是「分布式有条件类型」,但是分布式有条件类型是有前提的,条件类型里待检查的类型必须是naked type parameter</p> <p>裸类型分发，不是裸类型不分发，下面示例中的T不是裸类型</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//none naked type</span>
type Condition<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token constant">T</span><span class="token punctuation">]</span> <span class="token keyword">extends</span> <span class="token punctuation">[</span>Fish<span class="token punctuation">]</span> <span class="token operator">?</span> Water <span class="token operator">:</span> Sky<span class="token punctuation">;</span><span class="token comment">// T被包裹了，这样不行  会返回sky</span>
<span class="token keyword">let</span> condition2<span class="token operator">:</span> Condition<span class="token operator">&lt;</span>Fish <span class="token operator">|</span> Bird<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> sky<span class="token operator">:</span> <span class="token string">'天空'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token comment">// 找出T类型中U不包含的部分</span>
<span class="token comment">//never会被自动过滤</span>
type Diff<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>

<span class="token comment">// 原则：T从左往右逐个判断是不是U的子类型</span>
type <span class="token constant">R</span> <span class="token operator">=</span> Diff<span class="token operator">&lt;</span><span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;d&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>  <span class="token comment">// never | never | never | d = &quot;d&quot;</span>
type <span class="token constant">R1</span> <span class="token operator">=</span> Diff<span class="token operator">&lt;</span><span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;d&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;f&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>  <span class="token comment">// &quot;b&quot; | &quot;d&quot;</span>

type Filter<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> <span class="token constant">T</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

type <span class="token constant">R2</span> <span class="token operator">=</span> Filter<span class="token operator">&lt;</span><span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;d&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// &quot;a&quot; | &quot;b&quot; | &quot;c&quot;</span>

type <span class="token constant">R3</span> <span class="token operator">=</span> Filter<span class="token operator">&lt;</span>string <span class="token operator">|</span> number <span class="token operator">|</span> boolean<span class="token punctuation">,</span> number<span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// number</span>
</code></pre></div><h2 id="内置条件类型"><a href="#内置条件类型" class="header-anchor">#</a> 内置条件类型</h2> <ul><li>TS 在内置了一些常用的条件类型，可以在 lib.es5.d.ts 中查看：</li> <li>utility-types</li></ul> <h3 id="exclude"><a href="#exclude" class="header-anchor">#</a> Exclude</h3> <p>从 T 可分配给的类型中排除 U</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  type Exclude<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>
  type  <span class="token constant">E</span> <span class="token operator">=</span> Exclude<span class="token operator">&lt;</span>string<span class="token operator">|</span>number<span class="token punctuation">,</span>string<span class="token operator">&gt;</span><span class="token punctuation">;</span>
  <span class="token keyword">let</span> e<span class="token operator">:</span><span class="token constant">E</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span class="token punctuation">{</span>
  type Exclude<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>
  type  <span class="token constant">E</span> <span class="token operator">=</span> Exclude<span class="token operator">&lt;</span><span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;d&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// d</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="extract"><a href="#extract" class="header-anchor">#</a> Extract</h3> <p>从 T 可分配的类型中提取 U</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  type Extract<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> <span class="token constant">T</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

  type  <span class="token constant">E</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span>string<span class="token operator">|</span>number<span class="token punctuation">,</span>string<span class="token operator">&gt;</span><span class="token punctuation">;</span>
  <span class="token keyword">let</span> e<span class="token operator">:</span><span class="token constant">E</span> <span class="token operator">=</span> <span class="token string">'1'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token punctuation">{</span>
  type Extract<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> <span class="token constant">T</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

  type  <span class="token constant">E</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span><span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;d&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;b&quot;</span> <span class="token operator">|</span> <span class="token string">&quot;c&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// &quot;a&quot; | &quot;b&quot; | &quot;c&quot;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="nonnullable"><a href="#nonnullable" class="header-anchor">#</a> NonNullable</h3> <p>从 T 中排除 null 和 undefined</p> <div class="language-js extra-class"><pre class="language-js"><code>type NonNullable<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">null</span> <span class="token operator">|</span> <span class="token keyword">undefined</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>
type  <span class="token constant">E</span> <span class="token operator">=</span> NonNullable<span class="token operator">&lt;</span>string<span class="token operator">|</span>number<span class="token operator">|</span><span class="token keyword">null</span><span class="token operator">|</span><span class="token keyword">undefined</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// string | number</span>
<span class="token keyword">let</span> e<span class="token operator">:</span><span class="token constant">E</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="returntype"><a href="#returntype" class="header-anchor">#</a> ReturnType</h3> <p><a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-inference-in-conditional-types" target="_blank" rel="noopener noreferrer">infer<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>最早出现在此 <a href="https://github.com/Microsoft/TypeScript/pull/21496" target="_blank" rel="noopener noreferrer">PR<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>中，表示在 extends 条件语句中待推断的类型变量，获取函数类型的返回类型</p> <div class="language-js extra-class"><pre class="language-js"><code>type ReturnType<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args<span class="token operator">:</span> any<span class="token punctuation">[</span><span class="token punctuation">]</span></span><span class="token punctuation">)</span><span class="token operator">=&gt;</span>infer <span class="token constant">R</span> <span class="token operator">?</span> <span class="token constant">R</span> <span class="token operator">:</span> <span class="token constant">T</span>
<span class="token keyword">function</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">'f'</span><span class="token punctuation">,</span> age<span class="token operator">:</span> <span class="token number">18</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
type GetUserType <span class="token operator">=</span> <span class="token keyword">typeof</span> getUser
type ReturnUser <span class="token operator">=</span> ReturnType<span class="token operator">&lt;</span>GetUserType<span class="token operator">&gt;</span>
<span class="token keyword">let</span> u<span class="token operator">:</span> ReturnUser <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'f'</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span> <span class="token number">18</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="parameters"><a href="#parameters" class="header-anchor">#</a> Parameters</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
type Parameters<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args<span class="token operator">:</span> infer <span class="token constant">R</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> any <span class="token operator">?</span> <span class="token constant">R</span> <span class="token operator">:</span> any<span class="token punctuation">;</span>

type <span class="token constant">T0</span> <span class="token operator">=</span> Parameters<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> string<span class="token operator">&gt;</span><span class="token punctuation">;</span>  <span class="token comment">// []</span>
type <span class="token constant">T1</span> <span class="token operator">=</span> Parameters<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token parameter">s<span class="token operator">:</span> string</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>  <span class="token comment">// [string]</span>
type <span class="token constant">T2</span> <span class="token operator">=</span> Parameters<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token parameter">arg<span class="token operator">:</span> <span class="token constant">T</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>  <span class="token comment">// [unknown]</span>
</code></pre></div><h3 id="instancetype"><a href="#instancetype" class="header-anchor">#</a> InstanceType</h3> <ul><li>获取构造函数类型的实例类型</li> <li>InstanceType</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>type Constructor <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args<span class="token operator">:</span> any<span class="token punctuation">[</span><span class="token punctuation">]</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> any<span class="token punctuation">;</span>
  
type ConstructorParameters<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">Constructor</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">new</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args<span class="token operator">:</span> infer <span class="token constant">P</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> any <span class="token operator">?</span> <span class="token constant">P</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

type InstanceType<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">Constructor</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">new</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args<span class="token operator">:</span> any<span class="token punctuation">[</span><span class="token punctuation">]</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> infer <span class="token constant">R</span> <span class="token operator">?</span> <span class="token constant">R</span> <span class="token operator">:</span> any<span class="token punctuation">;</span>


<span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> string<span class="token punctuation">;</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token operator">:</span> string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//构造函数参数</span>
type constructorParameters <span class="token operator">=</span> ConstructorParameters<span class="token operator">&lt;</span><span class="token keyword">typeof</span> Person<span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> params<span class="token operator">:</span> constructorParameters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">]</span>

<span class="token comment">//实例类型</span>
type Instance <span class="token operator">=</span> InstanceType<span class="token operator">&lt;</span><span class="token keyword">typeof</span> Person<span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> instance<span class="token operator">:</span> Instance <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="infer-分布式"><a href="#infer-分布式" class="header-anchor">#</a> infer+分布式</h3> <ul><li>distributive-conditional-types</li> <li>「Distributive conditional types」主要用于拆分 extends 左边部分的联合类型</li> <li>「Distributive conditional types」是由「naked type parameter」构成的条件类型。而「naked type parameter」表示没有被 Wrapped 的类型（如：Array、[T]、Promise 等都是不是「naked type parameter」）。「Distributive conditional types」主要用于拆分 extends 左边部分的联合类型，举个例子：在条件类型 T extends U ? X : Y 中，当 T 是 A | B 时，会拆分成 A extends U ? X : Y | B extends U ? X : Y；</li> <li>利用在逆变位置上，同一类型变量的多个候选类型将会被推断为交叉类型的特性</li></ul> <p>tuple转union</p> <div class="language-js extra-class"><pre class="language-js"><code>type ElementOf<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">Array</span><span class="token operator">&lt;</span>infer <span class="token constant">E</span><span class="token operator">&gt;</span> <span class="token operator">?</span> <span class="token constant">E</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

type TTuple <span class="token operator">=</span> <span class="token punctuation">[</span>string<span class="token punctuation">,</span> number<span class="token punctuation">]</span><span class="token punctuation">;</span>

type ToUnion <span class="token operator">=</span> ElementOf<span class="token operator">&lt;</span>TTuple<span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// string | number</span>
</code></pre></div><p>联合类型转交叉类型</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//联合类型（Union Types）表示取值可以为多种类型中的一种</span>
<span class="token comment">//交叉类型（Intersection Types）表示将多个类型合并为一个类型</span>
<span class="token comment">//联合类型转交叉类型</span>
<span class="token comment">//union 转 intersection</span>
<span class="token comment">//union 转 intersection 的操作多用于 mixin 中</span>
<span class="token comment">//https://github.com/Microsoft/TypeScript/issues/27907</span>
type <span class="token constant">T1</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> string <span class="token punctuation">}</span><span class="token punctuation">;</span>
type <span class="token constant">T2</span> <span class="token operator">=</span> <span class="token punctuation">{</span> age<span class="token operator">:</span> number <span class="token punctuation">}</span><span class="token punctuation">;</span>

type UnionToIntersection<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token punctuation">{</span> <span class="token function-variable function">a</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> infer <span class="token constant">U</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function-variable function">b</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> infer <span class="token constant">U</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span> <span class="token punctuation">}</span> <span class="token operator">?</span> <span class="token constant">U</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>
type <span class="token constant">T3</span> <span class="token operator">=</span> UnionToIntersection<span class="token operator">&lt;</span><span class="token punctuation">{</span> <span class="token function-variable function">a</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> <span class="token constant">T1</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token punctuation">;</span> <span class="token function-variable function">b</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> <span class="token constant">T2</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span> <span class="token punctuation">}</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// T1 &amp; T2</span>
</code></pre></div><h2 id="内置工具类型"><a href="#内置工具类型" class="header-anchor">#</a> 内置工具类型</h2> <ul><li>TS 中内置了一些工具类型来帮助我们更好地使用类型系统
utility-types)</li> <li>TypeScript中增加了对映射类型修饰符的控制</li> <li>具体而言，一个 readonly 或 ? 修饰符在一个映射类型里可以用前缀 + 或-来表示这个修饰符应该被添加或移除</li></ul> <p>+?	变为可选</p> <p>-?	变为必选</p> <h3 id="partial"><a href="#partial" class="header-anchor">#</a> Partial</h3> <p>Partial 可以将传入的属性由非可选变为可选，具体使用如下</p> <div class="language-js extra-class"><pre class="language-js"><code>type Partial<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">interface</span> <span class="token class-name">A</span> <span class="token punctuation">{</span>
  a1<span class="token operator">:</span> string<span class="token punctuation">;</span>
  a2<span class="token operator">:</span> number<span class="token punctuation">;</span>
  a3<span class="token operator">:</span> boolean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

type aPartial <span class="token operator">=</span> Partial<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> a<span class="token operator">:</span> aPartial <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 不会报错</span>
</code></pre></div><h3 id="类型递归"><a href="#类型递归" class="header-anchor">#</a> 类型递归</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Company</span> <span class="token punctuation">{</span>
  id<span class="token operator">:</span> number
  name<span class="token operator">:</span> string
<span class="token punctuation">}</span>

<span class="token keyword">interface</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
    id<span class="token operator">:</span> number
    name<span class="token operator">:</span> string
    company<span class="token operator">:</span> Company
<span class="token punctuation">}</span>
<span class="token comment">// 这里的object是ts的内置类型</span>
type DeepPartial<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token punctuation">[</span><span class="token constant">U</span> <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">U</span><span class="token punctuation">]</span> <span class="token keyword">extends</span> <span class="token class-name">object</span>
    <span class="token operator">?</span> DeepPartial<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">U</span><span class="token punctuation">]</span><span class="token operator">&gt;</span>
    <span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">U</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

type <span class="token constant">R2</span> <span class="token operator">=</span> DeepPartial<span class="token operator">&lt;</span>Person<span class="token operator">&gt;</span>

<span class="token keyword">const</span> p<span class="token operator">:</span><span class="token constant">R2</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  id<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span>
  name<span class="token operator">:</span><span class="token string">'f'</span><span class="token punctuation">,</span>
  company<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// 如果没有DeepPartial，company中的属性必须要写，所以需要DeepPartial变为可选的</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="required"><a href="#required" class="header-anchor">#</a> Required</h3> <p>Required 可以将传入的属性中的可选项变为必选项，这里用了 -? 修饰符来实现。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span>number<span class="token punctuation">;</span>
  gender<span class="token operator">?</span><span class="token operator">:</span><span class="token string">'male'</span><span class="token operator">|</span><span class="token string">'female'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/**
 * type Require&lt;T&gt; = { [P in keyof T]-?: T[P] };
 */</span>
<span class="token keyword">let</span> p<span class="token operator">:</span>Required<span class="token operator">&lt;</span>Person<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>
  <span class="token comment">//gender:'male'</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="readonly-2"><a href="#readonly-2" class="header-anchor">#</a> Readonly</h3> <p>Readonly 通过为传入的属性每一项都加上 readonly 修饰符来实现</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span>number<span class="token punctuation">;</span>
  gender<span class="token operator">?</span><span class="token operator">:</span><span class="token string">'male'</span><span class="token operator">|</span><span class="token string">'female'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//type Readonly&lt;T&gt; = { readonly [P in keyof T]: T[P] };</span>
<span class="token keyword">let</span> p<span class="token operator">:</span>Readonly<span class="token operator">&lt;</span>Person<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>
  gender<span class="token operator">:</span><span class="token string">'male'</span>
<span class="token punctuation">}</span>
p<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span>
</code></pre></div><p>以上写法将Person中所有的属性定为了只读，如果我们只想其中某个属性只读该怎么办呢</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span>number<span class="token punctuation">;</span>
  gender<span class="token operator">?</span><span class="token operator">:</span><span class="token string">'male'</span><span class="token operator">|</span><span class="token string">'female'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//type Readonly&lt;T&gt; = { readonly [P in keyof T]: T[P] };</span>
type ReadOnlyName <span class="token operator">=</span> Person <span class="token operator">&amp;</span> <span class="token punctuation">{</span> readonly name<span class="token operator">:</span>string <span class="token punctuation">}</span>
<span class="token keyword">let</span> p<span class="token operator">:</span>ReadOnlyName<span class="token operator">&lt;</span>Person<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span><span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span>
  gender<span class="token operator">:</span><span class="token string">'male'</span>
<span class="token punctuation">}</span>
p<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="pick"><a href="#pick" class="header-anchor">#</a> Pick</h3> <p>Pick 能够帮助我们从传入的属性中摘取某一项返回</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> string<span class="token punctuation">;</span>
  age<span class="token operator">:</span> number<span class="token punctuation">;</span>
  married<span class="token operator">:</span> boolean
<span class="token punctuation">}</span>

type Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token class-name">keyof</span> <span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token constant">K</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 源码</span>
<span class="token comment">// keyof T是个啥</span>
type KeyOfPerson <span class="token operator">=</span> keyof Person <span class="token comment">// &quot;name&quot; | &quot;age&quot; | &quot;married&quot; 联合类型</span>

<span class="token keyword">let</span> person<span class="token operator">:</span> Person <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'fangfeiyue'</span><span class="token punctuation">,</span> age<span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> married<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
type PickPerson <span class="token operator">=</span> Pick<span class="token operator">&lt;</span>Person<span class="token punctuation">,</span> <span class="token string">'name'</span> <span class="token operator">|</span> <span class="token string">'age'</span><span class="token operator">&gt;</span> <span class="token comment">// {name: string; age: number;}</span>


<span class="token comment">// 和Extract对比</span>
type Extract<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> <span class="token constant">T</span> <span class="token operator">:</span> never<span class="token punctuation">;</span>

type  <span class="token constant">E</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span>string<span class="token operator">|</span>number<span class="token punctuation">,</span>string<span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> e<span class="token operator">:</span><span class="token constant">E</span> <span class="token operator">=</span> <span class="token string">'1'</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="record"><a href="#record" class="header-anchor">#</a> Record</h3> <ul><li>Record 是 TypeScript 的一个高级类型</li> <li>它会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>type Record<span class="token operator">&lt;</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token class-name">keyof</span> any<span class="token punctuation">,</span> <span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> <span class="token constant">K</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>
  <span class="token comment">/* 
  相当于
  [key:string]:string
  [key:number]:string
  */</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> k<span class="token operator">:</span>Record<span class="token operator">&lt;</span>string<span class="token operator">|</span>number<span class="token punctuation">,</span>string<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">'f'</span><span class="token punctuation">,</span> age<span class="token operator">:</span><span class="token string">'1'</span><span class="token punctuation">}</span>


<span class="token keyword">function</span> mapObject<span class="token operator">&lt;</span><span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token class-name">string</span> <span class="token operator">|</span> number<span class="token punctuation">,</span> <span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>obj<span class="token operator">:</span> Record<span class="token operator">&lt;</span><span class="token constant">K</span><span class="token punctuation">,</span> <span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">,</span> <span class="token function-variable function">map</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token operator">:</span> <span class="token constant">T</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token constant">U</span><span class="token punctuation">)</span><span class="token operator">:</span> Record<span class="token operator">&lt;</span><span class="token constant">K</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> result<span class="token operator">:</span> any <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      result<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">map</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> names <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">'hello'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">'world'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> lengths <span class="token operator">=</span> mapObject<span class="token operator">&lt;</span>string <span class="token operator">|</span> number<span class="token punctuation">,</span> string<span class="token punctuation">,</span> number<span class="token operator">&gt;</span><span class="token punctuation">(</span>names<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">s<span class="token operator">:</span> string</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> s<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>lengths<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//{ '0': 5, '1': 5 }</span>
</code></pre></div><h2 id="自定义高级类型"><a href="#自定义高级类型" class="header-anchor">#</a> 自定义高级类型</h2> <p>utility-types类库</p> <h3 id="proxy"><a href="#proxy" class="header-anchor">#</a> Proxy</h3> <div class="language-js extra-class"><pre class="language-js"><code>type Proxy<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;=</span> <span class="token punctuation">{</span>
  <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">,</span>
  <span class="token function">set</span><span class="token punctuation">(</span>value<span class="token operator">:</span><span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
type Proxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span>Proxy<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> proxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>obj<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">)</span><span class="token operator">:</span>Proxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token operator">&lt;</span>Proxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;&gt;</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token function-variable function">get</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'get '</span><span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token function-variable function">set</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'set '</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
        obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">Props</span><span class="token punctuation">{</span>
  name<span class="token operator">:</span>string<span class="token punctuation">;</span>
  age<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> props<span class="token operator">:</span> Props <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span><span class="token string">'zhufeng'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span><span class="token string">'k'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> proxyProps<span class="token operator">:</span>any <span class="token operator">=</span> proxify<span class="token operator">&lt;</span>Props<span class="token operator">&gt;</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>proxyProps<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>proxyProps<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
proxyProps<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'jiagou'</span><span class="token punctuation">;</span>
proxyProps<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token string">'k'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>proxyProps<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 取消代理</span>
<span class="token keyword">function</span> unProxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>t<span class="token operator">:</span> Proxify<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token constant">T</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> result<span class="token operator">:</span>any <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">as</span> <span class="token constant">T</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> k <span class="token keyword">in</span> t<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    result<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">[</span>k<span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> originProps <span class="token operator">=</span> unProxify<span class="token operator">&lt;</span>Props<span class="token operator">&gt;</span><span class="token punctuation">(</span>proxyProps<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>originProps<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="setdifference"><a href="#setdifference" class="header-anchor">#</a> SetDifference</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// SetDifference</span>
type SetDifference<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">B</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">;</span>

type <span class="token constant">A</span> <span class="token operator">=</span> string<span class="token operator">|</span>number
type <span class="token constant">B</span> <span class="token operator">=</span> string<span class="token operator">|</span>boolean

type <span class="token constant">AB</span> <span class="token operator">=</span> SetDifference<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token operator">&gt;</span> <span class="token comment">// number</span>
</code></pre></div><h3 id="omit"><a href="#omit" class="header-anchor">#</a> Omit</h3> <ul><li>Exclude 的作用是从 T 中排除出可分配给 U的元素.</li> <li>Omit&lt;T, K&gt;的作用是忽略T中的某些属性</li> <li>Omit = Exclude + Pick</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Omit</span>
type SetDifference<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">B</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">;</span>
<span class="token comment">// keyof取到的是 string | number | symbol</span>
type Omit<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">K</span> <span class="token keyword">extends</span> <span class="token class-name">keyof</span> any<span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> SetDifference<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">K</span><span class="token operator">&gt;&gt;</span><span class="token punctuation">;</span>

<span class="token comment">// 需求：忽略某些属性,ts已内置Omit</span>
<span class="token comment">// type Omit&lt;T, K extends keyof any&gt;  例子，未完成</span>
type props <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> string<span class="token punctuation">,</span> age<span class="token operator">:</span> number<span class="token punctuation">,</span> married<span class="token operator">:</span> boolean<span class="token punctuation">}</span>
type OmitAge <span class="token operator">=</span> Omit<span class="token operator">&lt;</span>props<span class="token punctuation">,</span> <span class="token string">'age'</span><span class="token operator">&gt;</span> <span class="token comment">// {name: string;married: boolean;}</span>
</code></pre></div><p>Omit的作用，排除某些属性</p> <h3 id="diff"><a href="#diff" class="header-anchor">#</a> Diff</h3> <div class="language-js extra-class"><pre class="language-js"><code>type SetDifference<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">B</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">;</span>
type Diff<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span>SetDifference<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;&gt;</span>

type Props <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> string<span class="token punctuation">,</span> age<span class="token operator">:</span> number<span class="token punctuation">,</span> visible<span class="token operator">:</span> boolean<span class="token punctuation">}</span>
type DefaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>age<span class="token operator">:</span> number<span class="token punctuation">}</span>
type DiffProps <span class="token operator">=</span> Diff<span class="token operator">&lt;</span>Props<span class="token punctuation">,</span> DefaultProps<span class="token operator">&gt;</span> <span class="token comment">//{name: string; visible: boolean;}</span>
</code></pre></div><h3 id="intersection"><a href="#intersection" class="header-anchor">#</a> Intersection</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Intersection 交叉属性</span>
type Intersection<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">&amp;</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">U</span><span class="token punctuation">,</span> keyof <span class="token constant">T</span><span class="token operator">&gt;&gt;</span>

type Props <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> string<span class="token punctuation">,</span> age<span class="token operator">:</span> number<span class="token punctuation">,</span> visible<span class="token operator">:</span> boolean<span class="token punctuation">}</span>
type DefaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>age<span class="token operator">:</span> number<span class="token punctuation">}</span>
type res<span class="token operator">=</span> Intersection<span class="token operator">&lt;</span>Props<span class="token punctuation">,</span> DefaultProps<span class="token operator">&gt;</span> <span class="token comment">// {age: number;}</span>
</code></pre></div><h3 id="overwrite"><a href="#overwrite" class="header-anchor">#</a> Overwrite</h3> <ul><li>Overwrite&lt;T, U&gt;顾名思义,是用U的属性覆盖T的相同属性，注意是只覆盖不添加，如果U中的属性比T中的多，多余且不重合的会被舍弃</li> <li>mapped-types</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Overwrite 重写</span>
type Intersection<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">&amp;</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">U</span><span class="token punctuation">,</span> keyof <span class="token constant">T</span><span class="token operator">&gt;&gt;</span>

type SetDifference<span class="token operator">&lt;</span><span class="token constant">A</span><span class="token punctuation">,</span> <span class="token constant">B</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">B</span> <span class="token operator">?</span> never <span class="token operator">:</span> <span class="token constant">A</span>

type Diff<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span>SetDifference<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;&gt;</span>

type Overwrite<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span>
<span class="token comment">// Diff&lt;T, U&gt;：{name: string;visible: boolean}</span>
<span class="token comment">// Intersection&lt;U, T&gt;：{age: number;}</span>
<span class="token comment">// 得I：{name: string; visible: boolean; age: number;}</span>
<span class="token constant">I</span> <span class="token operator">=</span> Diff<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">&amp;</span> Intersection<span class="token operator">&lt;</span><span class="token constant">U</span><span class="token punctuation">,</span> <span class="token constant">T</span><span class="token operator">&gt;&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">I</span><span class="token punctuation">,</span> keyof <span class="token constant">I</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>

type Props <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> string<span class="token punctuation">;</span> age<span class="token operator">:</span> number<span class="token punctuation">;</span> visible<span class="token operator">:</span> boolean <span class="token punctuation">}</span><span class="token punctuation">;</span>
type NewProps <span class="token operator">=</span> <span class="token punctuation">{</span> age<span class="token operator">:</span> string<span class="token punctuation">;</span> other<span class="token operator">:</span> string <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// Expect: { name: string; age: string; visible: boolean; }</span>
type ReplacedProps <span class="token operator">=</span> Overwrite<span class="token operator">&lt;</span>Props<span class="token punctuation">,</span> NewProps<span class="token operator">&gt;</span><span class="token punctuation">;</span>

<span class="token punctuation">{</span>
  <span class="token comment">// 源码中是直接把{other: string;}去掉的</span>
  type Overwrite<span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">U</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span>
  <span class="token comment">// Diff&lt;T, U&gt;：{name: string;visible: boolean}</span>
  <span class="token comment">// U：{ age: string; other: string }</span>
  <span class="token comment">// 得I：{name: string; visible: boolean; age: number;}</span>
  <span class="token constant">I</span> <span class="token operator">=</span> Diff<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">&amp;</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Pick<span class="token operator">&lt;</span><span class="token constant">I</span><span class="token punctuation">,</span> keyof <span class="token constant">I</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
  <span class="token comment">// Expect: { name: string; age: string; visible: boolean; other: string;}</span>
  type ReplacedProps <span class="token operator">=</span> Overwrite<span class="token operator">&lt;</span>Props<span class="token punctuation">,</span> NewProps<span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>以下代码的输出是否相同，答案是相同的</p> <div class="language-js extra-class"><pre class="language-js"><code>type <span class="token constant">I1</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">&amp;</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">U</span><span class="token punctuation">,</span> keyof <span class="token constant">T</span><span class="token operator">&gt;</span>
type <span class="token constant">I2</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">T</span><span class="token punctuation">,</span> keyof <span class="token constant">U</span><span class="token operator">&gt;</span>
type <span class="token constant">I3</span><span class="token operator">&lt;</span><span class="token constant">T</span><span class="token punctuation">,</span> <span class="token constant">U</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Extract<span class="token operator">&lt;</span>keyof <span class="token constant">U</span><span class="token punctuation">,</span> keyof <span class="token constant">T</span><span class="token operator">&gt;</span>

type <span class="token constant">T1</span> <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span>string<span class="token punctuation">,</span> age<span class="token operator">:</span>number<span class="token punctuation">}</span>
type <span class="token constant">T2</span> <span class="token operator">=</span> <span class="token punctuation">{</span>age<span class="token operator">:</span>string<span class="token punctuation">,</span> married<span class="token operator">:</span>boolean<span class="token punctuation">}</span>

type <span class="token constant">R1</span> <span class="token operator">=</span> <span class="token constant">I1</span><span class="token operator">&lt;</span><span class="token constant">T1</span><span class="token punctuation">,</span> <span class="token constant">T2</span><span class="token operator">&gt;</span> <span class="token comment">// 'age'</span>
type <span class="token constant">R2</span> <span class="token operator">=</span> <span class="token constant">I2</span><span class="token operator">&lt;</span><span class="token constant">T1</span><span class="token punctuation">,</span> <span class="token constant">T2</span><span class="token operator">&gt;</span> <span class="token comment">// 'age'</span>
type <span class="token constant">R3</span> <span class="token operator">=</span> <span class="token constant">I3</span><span class="token operator">&lt;</span><span class="token constant">T1</span><span class="token punctuation">,</span> <span class="token constant">T2</span><span class="token operator">&gt;</span> <span class="token comment">// 'age'</span>
</code></pre></div><h3 id="merge"><a href="#merge" class="header-anchor">#</a> Merge</h3> <ul><li>Merge&lt;O1, O2&gt;的作用是将两个对象的属性合并:</li> <li>Merge&lt;O1, O2&gt; = Compute + Omit&lt;U, T&gt;</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//Compute的作用是将交叉类型合并</span>
type Compute<span class="token operator">&lt;</span><span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">any</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token constant">A</span> <span class="token keyword">extends</span> <span class="token class-name">Function</span> <span class="token operator">?</span> <span class="token constant">A</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">K</span> <span class="token keyword">in</span> keyof <span class="token constant">A</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">A</span><span class="token punctuation">[</span><span class="token constant">K</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

type <span class="token constant">R1</span> <span class="token operator">=</span> Compute<span class="token operator">&lt;</span><span class="token punctuation">{</span> x<span class="token operator">:</span> <span class="token string">&quot;x&quot;</span> <span class="token punctuation">}</span> <span class="token operator">&amp;</span> <span class="token punctuation">{</span> y<span class="token operator">:</span> <span class="token string">&quot;y&quot;</span> <span class="token punctuation">}</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// {x: &quot;x&quot;;y: &quot;y&quot;;}</span>
type Merge<span class="token operator">&lt;</span><span class="token constant">O1</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token punctuation">,</span> <span class="token constant">O2</span> <span class="token keyword">extends</span> <span class="token class-name">object</span><span class="token operator">&gt;</span> <span class="token operator">=</span> Compute<span class="token operator">&lt;</span><span class="token constant">O1</span> <span class="token operator">&amp;</span> Omit<span class="token operator">&lt;</span><span class="token constant">O2</span><span class="token punctuation">,</span>keyof <span class="token constant">O1</span><span class="token operator">&gt;&gt;</span><span class="token punctuation">;</span>

type <span class="token constant">O</span> <span class="token operator">=</span> Omit<span class="token operator">&lt;</span><span class="token constant">O2</span><span class="token punctuation">,</span> keyof <span class="token constant">O1</span><span class="token operator">&gt;</span> <span class="token comment">// {age: number;}</span>

type <span class="token constant">O1</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  id<span class="token operator">:</span> number<span class="token punctuation">;</span>
  name<span class="token operator">:</span> string<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

type <span class="token constant">O2</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  id<span class="token operator">:</span> number<span class="token punctuation">;</span>
  age<span class="token operator">:</span> number<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

type <span class="token constant">R2</span> <span class="token operator">=</span> Merge<span class="token operator">&lt;</span><span class="token constant">O1</span><span class="token punctuation">,</span> <span class="token constant">O2</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// {id: number;name: string;age: number;}</span>
</code></pre></div><h3 id="mutable"><a href="#mutable" class="header-anchor">#</a> Mutable</h3> <p>将 T 的所有属性的 readonly 移除</p> <div class="language-js extra-class"><pre class="language-js"><code>type Mutable<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token operator">-</span>readonly <span class="token punctuation">[</span><span class="token constant">P</span> <span class="token keyword">in</span> keyof <span class="token constant">T</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">[</span><span class="token constant">P</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>

</code></pre></div><h1 id="模块vs命名空间"><a href="#模块vs命名空间" class="header-anchor">#</a> 模块vs命名空间</h1> <h2 id="模块"><a href="#模块" class="header-anchor">#</a> 模块</h2> <h3 id="全局模块"><a href="#全局模块" class="header-anchor">#</a> 全局模块</h3> <p>在默认情况下，当开始在一个新的 TypeScript 文件中写下代码时，在这个文件中声明的变量、函数等默认处于全局命名空间中，当在两个文件中使用了同样的变量名就会报错，如下我们新建两个ts文件，文件中分别定义一个常量foo，会发现foo出现了红色波浪线，鼠标放上去会提示'foo' was also declared here.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.ts</span>
<span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span>

<span class="token comment">// 2.ts</span>
<span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">456</span><span class="token punctuation">;</span>
</code></pre></div><p>使用全局变量空间是危险的，因为它会与文件内的代码命名冲突，推荐使用文件模块。</p> <h3 id="文件模块"><a href="#文件模块" class="header-anchor">#</a> 文件模块</h3> <ul><li>文件模块也被称为外部模块。如果在你的 TypeScript 文件的根级别位置含有 import 或者 export，那么它会在这个文件中创建一个本地的作用域</li> <li>模块是TS中外部模块的简称，侧重于代码和复用</li> <li>模块在期自身的作用域里执行，而不是在全局作用域里</li> <li>一个模块里的变量、函数、类等在外部是不可见的，除非你把它导出</li> <li>如果想要使用一个模块里导出的变量，则需要导入</li></ul> <p>将上述代码做如下修改，就不会有错误提示了</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.ts</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">123</span>
<span class="token comment">// 2.ts</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">456</span>
</code></pre></div><p>一个模块里的变量、函数、类等在外部是不可见的，如果想在其他地方使用某个模块中的变量、函数等，需要把它们导出</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 3.ts</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">'f'</span>

<span class="token comment">// index.ts</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./3'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="模块规范"><a href="#模块规范" class="header-anchor">#</a> 模块规范</h3> <p>文件模块的使用也是要遵守一定原则的，不是想怎么来就来的，在前端发展过程中出现了许多优秀的前端模块规范，在ts中建议使用commonJS规范，原因如下</p> <ul><li>AMD：不要使用它，它仅能在浏览器工作；</li> <li>SystemJS：这是一个好的实验，已经被 ES 模块替代；</li> <li>ES 模块：浏览器等还不能原生支持。</li> <li>使用 module: commonjs 选项来替代这些模式，将会是一个好的主意</li></ul> <h2 id="命名空间"><a href="#命名空间" class="header-anchor">#</a> 命名空间</h2> <p>当我们的项目比较大的时候，在一个文件模块中可能会定义很多变量、函数等，难免会忘记哪些名字是否重复定义了造成命名冲突，这个时候我们就需要使用命名空间来解决这种冲突。</p> <ul><li>在代码量较大的情况下，为了避免命名空间冲突，可以将相似的函数、类、接口放置到命名空间内</li> <li>命名空间可以将代码包裹起来，只对外暴露需要在外部访问的对象，命名空间内通过export向外导出</li> <li>命名空间是内部模块，主要用于组织代码，避免命名冲突</li></ul> <p>以下两点需要注意：</p> <p>不同模块下同名的命名空间不会合并</p> <div class="language-js extra-class"><pre class="language-js"><code>module <span class="token constant">A</span><span class="token punctuation">{</span>
  namespace <span class="token constant">B</span><span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">2</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

module <span class="token constant">B</span><span class="token punctuation">{</span>
  namespace <span class="token constant">B</span> <span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">1</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 编译成js的代码如下</span>
<span class="token keyword">var</span> <span class="token constant">A</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> <span class="token constant">B</span><span class="token punctuation">;</span>
    <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token constant">B</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token constant">B</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">B_1</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> <span class="token constant">B</span><span class="token punctuation">;</span>
    <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">B</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token constant">B</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">B</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>同一模块下名字相同的命名空间会合并</p> <div class="language-js extra-class"><pre class="language-js"><code>namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span>
<span class="token punctuation">}</span>

namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">2</span>
<span class="token punctuation">}</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">.</span>a<span class="token punctuation">,</span> <span class="token constant">A</span><span class="token punctuation">.</span>b<span class="token punctuation">)</span> <span class="token comment">// 1 2</span>

<span class="token comment">// 编译成js的代码如下</span>
<span class="token keyword">var</span> <span class="token constant">A</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">.</span>a<span class="token punctuation">,</span> <span class="token constant">A</span><span class="token punctuation">.</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 2</span>
</code></pre></div><h3 id="内部划分"><a href="#内部划分" class="header-anchor">#</a> 内部划分</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> namespace zoo <span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Dog</span> <span class="token punctuation">{</span> <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'zoo dog'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> namespace home <span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Dog</span> <span class="token punctuation">{</span> <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'home dog'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> dog_of_zoo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">zoo<span class="token punctuation">.</span>Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
dog_of_zoo<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> dog_of_home <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">home<span class="token punctuation">.</span>Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
dog_of_home<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token keyword">import</span> <span class="token punctuation">{</span> zoo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./3'</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> dog_of_zoo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">zoo<span class="token punctuation">.</span>Dog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
dog_of_zoo<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="原理"><a href="#原理" class="header-anchor">#</a> 原理</h3> <p>命名空间本质上是一个对象，它的作用是将一系列相关的全局变量组织到一个对象的属性</p> <div class="language-js extra-class"><pre class="language-js"><code>namespace Numbers <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">export</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
  <span class="token keyword">export</span> <span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 编译成js后的代码</span>
<span class="token keyword">var</span> Numbers<span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">Numbers</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    Numbers<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    Numbers<span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
    Numbers<span class="token punctuation">.</span>c <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>Numbers <span class="token operator">||</span> <span class="token punctuation">(</span>Numbers <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="文件、模块与命名空间"><a href="#文件、模块与命名空间" class="header-anchor">#</a> 文件、模块与命名空间</h2> <p>命名空间具有全局唯一性，如果不是在模块内使用，全局只能有一个同名的命名空间。模块之间是相互独立的，可以存在同名的模块</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.ts</span>
namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2.ts</span>
namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">2</span> <span class="token comment">// Cannot redeclare block-scoped variable 'a'</span>
<span class="token punctuation">}</span>
</code></pre></div><p>上述代码会提示 Cannot redeclare block-scoped variable 'a'</p> <p>考察</p> <div class="language-js extra-class"><pre class="language-js"><code>module <span class="token constant">A</span><span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span>
<span class="token punctuation">}</span>

module <span class="token constant">A</span><span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">2</span>
<span class="token punctuation">}</span>

namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> c <span class="token operator">=</span> <span class="token number">3</span>
<span class="token punctuation">}</span>

namespace <span class="token constant">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">const</span> d <span class="token operator">=</span> <span class="token number">4</span>
<span class="token punctuation">}</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">.</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>

<span class="token comment">// 编译成js后</span>
<span class="token keyword">var</span> <span class="token constant">A</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>c <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">A</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token constant">A</span><span class="token punctuation">.</span>d <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token constant">A</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">A</span><span class="token punctuation">.</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="类型声明"><a href="#类型声明" class="header-anchor">#</a> 类型声明</h2> <ul><li>声明文件可以让我们不需要将JS重构为TS，只需要加上声明文件就可以使用系统</li> <li>类型声明在编译的时候都会被删除，不会影响真正的代码</li> <li>关键字 declare 表示声明的意思,我们可以用它来做出各种声明:</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">var</span> 声明全局变量
declare <span class="token keyword">function</span> 声明全局方法
declare <span class="token keyword">class</span> 声明全局类
declare <span class="token keyword">enum</span> 声明全局枚举类型
declare namespace <span class="token function">声明</span><span class="token punctuation">(</span>含有子属性的<span class="token punctuation">)</span>全局对象
<span class="token keyword">interface</span> 和 type 声明全局类型
</code></pre></div><h3 id="普通类型声明"><a href="#普通类型声明" class="header-anchor">#</a> 普通类型声明</h3> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">let</span> name<span class="token operator">:</span> string<span class="token punctuation">;</span>  <span class="token comment">//变量</span>
declare <span class="token keyword">let</span> age<span class="token operator">:</span> number<span class="token punctuation">;</span>  <span class="token comment">//变量</span>
declare <span class="token keyword">function</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> string<span class="token punctuation">;</span>  <span class="token comment">//方法</span>
declare <span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> string <span class="token punctuation">}</span>  <span class="token comment">//类</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> age<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="外部枚举"><a href="#外部枚举" class="header-anchor">#</a> 外部枚举</h3> <ul><li>外部枚举是使用declare enum定义的枚举类型</li> <li>外部枚举用来描述已经存在的枚举类型的形状</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">enum</span> Seasons <span class="token punctuation">{</span>
    Spring<span class="token punctuation">,</span>
    Summer<span class="token punctuation">,</span>
    Autumn<span class="token punctuation">,</span>
    Winter
<span class="token punctuation">}</span>

<span class="token keyword">let</span> seasons <span class="token operator">=</span> <span class="token punctuation">[</span>
    Seasons<span class="token punctuation">.</span>Spring<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Summer<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Autumn<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Winter
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>declare 定义的类型只会用于编译时的检查，编译结果中会被删除。上例的编译结果如下</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> seasons <span class="token operator">=</span> <span class="token punctuation">[</span>
  Seasons<span class="token punctuation">.</span>Spring<span class="token punctuation">,</span>
  Seasons<span class="token punctuation">.</span>Summer<span class="token punctuation">,</span>
  Seasons<span class="token punctuation">.</span>Autumn<span class="token punctuation">,</span>
  Seasons<span class="token punctuation">.</span>Winter
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>也可以同时使用declare 和 const</p> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">const</span> <span class="token keyword">enum</span> Seasons <span class="token punctuation">{</span>
    Spring<span class="token punctuation">,</span>
    Summer<span class="token punctuation">,</span>
    Autumn<span class="token punctuation">,</span>
    Winter
<span class="token punctuation">}</span>

<span class="token keyword">let</span> seasons <span class="token operator">=</span> <span class="token punctuation">[</span>
    Seasons<span class="token punctuation">.</span>Spring<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Summer<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Autumn<span class="token punctuation">,</span>
    Seasons<span class="token punctuation">.</span>Winter
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>编译结果</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> seasons <span class="token operator">=</span> <span class="token punctuation">[</span>
    <span class="token number">0</span> <span class="token comment">/* Spring */</span><span class="token punctuation">,</span>
    <span class="token number">1</span> <span class="token comment">/* Summer */</span><span class="token punctuation">,</span>
    <span class="token number">2</span> <span class="token comment">/* Autumn */</span><span class="token punctuation">,</span>
    <span class="token number">3</span> <span class="token comment">/* Winter */</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="命名空间-2"><a href="#命名空间-2" class="header-anchor">#</a> 命名空间</h3> <ul><li>如果一个全局变量包括了很多子属性，可能使用namespace</li> <li>在声明文件中的namespace表示一个全局变量包含很多子属性</li> <li>在命名空间内部不需要使用 declare 声明属性或方法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>declare namespace $<span class="token punctuation">{</span>
    <span class="token keyword">function</span> <span class="token function">ajax</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token operator">:</span>string<span class="token punctuation">,</span>settings<span class="token operator">:</span>any</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> name<span class="token operator">:</span>string<span class="token punctuation">;</span>
    namespace fn <span class="token punctuation">{</span>
        <span class="token keyword">function</span> <span class="token function">extend</span><span class="token punctuation">(</span><span class="token parameter">object<span class="token operator">:</span>any</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'/api/users'</span><span class="token punctuation">,</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
$<span class="token punctuation">.</span>fn<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token function-variable function">log</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token operator">:</span>any</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="类型声明文件"><a href="#类型声明文件" class="header-anchor">#</a> 类型声明文件</h3> <ul><li>我们可以把类型声明放在一个单独的类型声明文件中</li> <li>可以在类型声明文件中使用类型声明</li> <li>文件命名规范为*.d.ts</li> <li>观看类型声明文件有助于了解库的使用方式</li></ul> <p>typings\jquery.d.ts</p> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">const</span> <span class="token function-variable function">$</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">selector<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
    <span class="token function">width</span><span class="token punctuation">(</span>length<span class="token operator">:</span>number<span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>tsconfig.json</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  <span class="token string">&quot;compilerOptions&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token string">&quot;module&quot;</span><span class="token operator">:</span> <span class="token string">&quot;commonjs&quot;</span><span class="token punctuation">,</span>
    <span class="token string">&quot;target&quot;</span><span class="token operator">:</span> <span class="token string">&quot;ES2015&quot;</span><span class="token punctuation">,</span>  
    <span class="token string">&quot;outDir&quot;</span><span class="token operator">:</span><span class="token string">&quot;lib&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token string">&quot;include&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token string">&quot;src/**/*&quot;</span><span class="token punctuation">,</span>
    <span class="token string">&quot;typings/**/*&quot;</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre></div><p>src\test.ts</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#button'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#button'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">width</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="第三方声明文件"><a href="#第三方声明文件" class="header-anchor">#</a> 第三方声明文件</h3> <ul><li>可以安装使用第三方的声明文件</li> <li>@types是一个约定的前缀，所有的第三方声明的类型库都会带有这样的前缀</li> <li>JavaScript 中有很多内置对象，它们可以在 TypeScript 中被当做声明好了的类型</li> <li>内置对象是指根据标准在全局作用域（Global）上存在的对象。这里的标准是指 ECMAScript 和其他环境（比如 DOM）的标准</li> <li>这些内置对象的类型声明文件，就包含在TypeScript 核心库的类型声明文件中</li></ul> <h4 id="使用jquery"><a href="#使用jquery" class="header-anchor">#</a> 使用jquery</h4> <div class="language-js extra-class"><pre class="language-js"><code>cnpm i jquery <span class="token operator">-</span><span class="token constant">S</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//对于common.js风格的模块必须使用 import * as </span>
<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> jQuery <span class="token keyword">from</span> <span class="token string">'jquery'</span><span class="token punctuation">;</span>
<span class="token comment">/* 
import jQuery from 'jquery' 
为什么会报错？
导出的时候用的是common.js，但是在你这里是通过es默认导出的
*/</span>
jQuery<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'/user/1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="安装声明文件"><a href="#安装声明文件" class="header-anchor">#</a> 安装声明文件</h4> <div class="language-js extra-class"><pre class="language-js"><code>cnpm i @types<span class="token operator">/</span>jquery <span class="token operator">-</span><span class="token constant">S</span>
</code></pre></div><h4 id="自己编写声明文件"><a href="#自己编写声明文件" class="header-anchor">#</a> 自己编写声明文件</h4> <ul><li>模块查找规则</li> <li>node_modules@types\jquery/index.d.ts</li> <li>我们可以自己编写声明文件并配置tsconfig.json</li></ul> <p>types\jquery\index.d.ts</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 这样声明的原因是jq既是一个函数也是一个对象，通过下面这种写法可以扩展函数属性</span>
declare <span class="token keyword">function</span> <span class="token function">jQuery</span><span class="token punctuation">(</span><span class="token parameter">selector<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token operator">:</span>HTMLElement<span class="token punctuation">;</span>
declare namespace jQuery<span class="token punctuation">{</span>
  <span class="token keyword">function</span> <span class="token function">ajax</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token operator">:</span>string</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token keyword">void</span>
<span class="token punctuation">}</span>
<span class="token comment">// export default jQuery; 如果这样导出jQuery，在使用的时候就要jQuery.default.ajax()这样调用很繁琐，推荐使用下面这种导出方式</span>
<span class="token keyword">export</span> <span class="token operator">=</span> jQuery <span class="token comment">// 这是一种ts的写法表示要导出jq</span>

</code></pre></div><h4 id="tsconfig-json"><a href="#tsconfig-json" class="header-anchor">#</a> tsconfig.json</h4> <ul><li>如果配置了paths,那么在引入包的的时候会自动去paths目录里找类型声明文件</li> <li>在 tsconfig.json 中，我们通过 compilerOptions 里的 paths 属性来配置路径映射</li> <li>paths是模块名到基于baseUrl的路径映射的列表</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  <span class="token string">&quot;compilerOptions&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token string">&quot;baseUrl&quot;</span><span class="token operator">:</span> <span class="token string">&quot;./&quot;</span><span class="token punctuation">,</span><span class="token comment">// 使用 paths 属性的话必须要指定 baseUrl 的值</span>
    <span class="token string">&quot;paths&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token string">&quot;*&quot;</span><span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">&quot;types/*&quot;</span><span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>index.ts</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> $ <span class="token keyword">from</span> <span class="token string">&quot;jquery&quot;</span><span class="token punctuation">;</span>
$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'get'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="npm声明文件可能的位置"><a href="#npm声明文件可能的位置" class="header-anchor">#</a> npm声明文件可能的位置</h4> <ul><li>node_modules/jquery/package.json
<ul><li>&quot;types&quot;:&quot;types/xxx.d.ts&quot;</li></ul></li> <li>node_modules/jquery/index.d.ts</li> <li>node_modules/@types/jquery/index.d.ts</li> <li>typings\jquery\index.d.ts</li></ul> <p>以上都找不到的话会报错</p> <h4 id="查找声明文件"><a href="#查找声明文件" class="header-anchor">#</a> 查找声明文件</h4> <ul><li>如果是手动写的声明文件，那么需要满足以下条件之一，才能被正确的识别</li> <li>给 package.json 中的 types 或 typings 字段指定一个类型声明文件地址</li> <li>在项目根目录下，编写一个 index.d.ts 文件</li> <li>针对入口文件（package.json 中的 main 字段指定的入口文件），编写一个同名不同后缀的 .d.ts 文件</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  <span class="token string">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;myLib&quot;</span><span class="token punctuation">,</span>
  <span class="token string">&quot;version&quot;</span><span class="token operator">:</span> <span class="token string">&quot;1.0.0&quot;</span><span class="token punctuation">,</span>
  <span class="token string">&quot;main&quot;</span><span class="token operator">:</span> <span class="token string">&quot;lib/index.js&quot;</span><span class="token punctuation">,</span>
  <span class="token string">&quot;types&quot;</span><span class="token operator">:</span> <span class="token string">&quot;myLib.d.ts&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>先找myLib.d.ts</li> <li>没有就再找index.d.ts</li> <li>还没有再找lib/index.d.js</li> <li>还找不到就认为没有类型声明了</li></ul> <h3 id="扩展全局变量的类型"><a href="#扩展全局变量的类型" class="header-anchor">#</a> 扩展全局变量的类型</h3> <h4 id="扩展局部变量类型"><a href="#扩展局部变量类型" class="header-anchor">#</a> 扩展局部变量类型</h4> <div class="language-js extra-class"><pre class="language-js"><code>declare <span class="token keyword">var</span> String<span class="token operator">:</span> StringConstructor<span class="token punctuation">;</span>
<span class="token keyword">interface</span> <span class="token class-name">StringConstructor</span> <span class="token punctuation">{</span>
  <span class="token comment">// string是基本类型，String是类</span>
  <span class="token keyword">new</span><span class="token punctuation">(</span>value<span class="token operator">?</span><span class="token operator">:</span> any<span class="token punctuation">)</span><span class="token operator">:</span> String<span class="token punctuation">;</span>
  <span class="token punctuation">(</span>value<span class="token operator">?</span><span class="token operator">:</span> any<span class="token punctuation">)</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
  readonly prototype<span class="token operator">:</span> String<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">interface</span> <span class="token class-name">String</span> <span class="token punctuation">{</span>
  <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//扩展类的原型</span>
<span class="token keyword">interface</span> <span class="token class-name">String</span> <span class="token punctuation">{</span>
    <span class="token function">double</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span>string<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token class-name">String</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">double</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token operator">+</span><span class="token string">'+'</span><span class="token operator">+</span><span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">.</span><span class="token function">double</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//扩展类的实例</span>
<span class="token keyword">interface</span> <span class="token class-name">Window</span><span class="token punctuation">{</span>
    myname<span class="token operator">:</span>string
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>myname<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//export {} 没有导出就是全局扩展</span>
</code></pre></div><h4 id="模块内全局扩展"><a href="#模块内全局扩展" class="header-anchor">#</a> 模块内全局扩展</h4> <p>上述代码的扩展是全局内的，如果给文件加上export，会报错，想要不报错需要像下面这样写global</p> <div class="language-js extra-class"><pre class="language-js"><code>declare global<span class="token punctuation">{</span>
  <span class="token keyword">interface</span> <span class="token class-name">String</span> <span class="token punctuation">{</span>
      <span class="token function">double</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span>string<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">interface</span> <span class="token class-name">Window</span><span class="token punctuation">{</span>
      myname<span class="token operator">:</span>string
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span>  <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre></div><h3 id="合并声明"><a href="#合并声明" class="header-anchor">#</a> 合并声明</h3> <ul><li>同一名称的两个独立声明会被合并成一个单一声明</li> <li>合并后的声明拥有原先两个声明的特性</li></ul> <table><thead><tr><th>关键字</th> <th style="text-align:center;">作为类型使用</th> <th style="text-align:right;">作为值使用</th></tr></thead> <tbody><tr><td>class</td> <td style="text-align:center;">yes</td> <td style="text-align:right;">yes</td></tr> <tr><td>enum</td> <td style="text-align:center;">yes</td> <td style="text-align:right;">yes</td></tr> <tr><td>interface</td> <td style="text-align:center;">yes</td> <td style="text-align:right;">no</td></tr> <tr><td>type</td> <td style="text-align:center;">yes</td> <td style="text-align:right;">no</td></tr> <tr><td>function</td> <td style="text-align:center;">no</td> <td style="text-align:right;">yes</td></tr> <tr><td>var,let,const</td> <td style="text-align:center;">no</td> <td style="text-align:right;">yes</td></tr></tbody></table> <p>类既可以作为类型使用，也可以作为值使用，接口只能作为类型使用</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">Person</span><span class="token punctuation">{</span>
    name<span class="token operator">:</span>string<span class="token operator">=</span><span class="token string">''</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> p1<span class="token operator">:</span>Person<span class="token punctuation">;</span><span class="token comment">//作为类型使用</span>
<span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//作为值使用</span>

<span class="token keyword">interface</span> <span class="token class-name">Animal</span><span class="token punctuation">{</span>
    name<span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> a1<span class="token operator">:</span>Animal<span class="token punctuation">;</span>
<span class="token keyword">let</span> a2 <span class="token operator">=</span> Animal<span class="token punctuation">;</span><span class="token comment">//接口类型不能用作值</span>
</code></pre></div><h4 id="合并类型声明"><a href="#合并类型声明" class="header-anchor">#</a> 合并类型声明</h4> <p>可以通过接口合并的特性给一个第三方为扩展类型声明</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Animal</span><span class="token punctuation">{</span>
    name<span class="token operator">:</span>string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> a1<span class="token operator">:</span>Animal<span class="token operator">=</span><span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'zhufeng'</span><span class="token punctuation">,</span>age<span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a1<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a1<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//注意不要加export {} ,这是全局的</span>
</code></pre></div><p>types\animal\index.d.ts</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">interface</span> <span class="token class-name">Animal</span><span class="token punctuation">{</span>
    age<span class="token operator">:</span>number
<span class="token punctuation">}</span>
</code></pre></div><h4 id="使用命名空间扩展类"><a href="#使用命名空间扩展类" class="header-anchor">#</a> 使用命名空间扩展类</h4> <p>我们可以使用 namespace 来扩展类，用于表示内部类</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">Form</span> <span class="token punctuation">{</span>
  username<span class="token operator">:</span> Form<span class="token punctuation">.</span>Item<span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Form<span class="token punctuation">.</span>Item</span><span class="token punctuation">;</span>
  password<span class="token operator">:</span> Form<span class="token punctuation">.</span>Item<span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Form<span class="token punctuation">.</span>Item</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//Item为Form的内部类</span>
namespace Form <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Item</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> item<span class="token operator">:</span>Form<span class="token punctuation">.</span>Item <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Form<span class="token punctuation">.</span>Item</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="使用命名空间扩展函数"><a href="#使用命名空间扩展函数" class="header-anchor">#</a> 使用命名空间扩展函数</h4> <p>我们也可以使用 namespace 来扩展函数</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">greeting</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token operator">:</span> string</span><span class="token punctuation">)</span><span class="token operator">:</span> string <span class="token punctuation">{</span>
    <span class="token keyword">return</span> greeting<span class="token punctuation">.</span>words<span class="token operator">+</span>name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

namespace greeting <span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">let</span> words <span class="token operator">=</span> <span class="token string">&quot;Hello,&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">greeting</span><span class="token punctuation">(</span><span class="token string">'zhufeng'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><h4 id="使用命名空间扩展枚举类型"><a href="#使用命名空间扩展枚举类型" class="header-anchor">#</a> 使用命名空间扩展枚举类型</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">enum</span> Color <span class="token punctuation">{</span>
    red <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span>
    yellow <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span>
    blue <span class="token operator">=</span> <span class="token number">3</span>
<span class="token punctuation">}</span>

namespace Color <span class="token punctuation">{</span>
    <span class="token keyword">export</span> <span class="token keyword">const</span> green<span class="token operator">=</span><span class="token number">4</span><span class="token punctuation">;</span>
    <span class="token keyword">export</span> <span class="token keyword">const</span> purple<span class="token operator">=</span><span class="token number">5</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Color<span class="token punctuation">.</span>green<span class="token punctuation">)</span>
</code></pre></div><h4 id="扩展store"><a href="#扩展store" class="header-anchor">#</a> 扩展Store</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> Store <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span><span class="token punctuation">;</span>
type StoreExt <span class="token operator">=</span> Store <span class="token operator">&amp;</span> <span class="token punctuation">{</span>
    ext<span class="token operator">:</span> string
<span class="token punctuation">}</span>
<span class="token keyword">let</span> store<span class="token operator">:</span> StoreExt <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span><span class="token parameter">state</span> <span class="token operator">=&gt;</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>
store<span class="token punctuation">.</span>ext <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="生成声明文件"><a href="#生成声明文件" class="header-anchor">#</a> 生成声明文件</h4> <p>把TS编译成JS后丢失类型声明，我们可以在编译的时候自动生成一份JS文件</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span>
  <span class="token string">&quot;compilerOptions&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
     <span class="token string">&quot;declaration&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">/* Generates corresponding '.d.ts' file.*/</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="类型声明实战"><a href="#类型声明实战" class="header-anchor">#</a> 类型声明实战</h3></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"><!----><!----></div></div>
    <script src="/assets/js/app.8c5a7a92.js" defer></script><script src="/assets/js/2.8e30e130.js" defer></script><script src="/assets/js/457.329d4d26.js" defer></script><script src="/assets/js/64.0323ed89.js" defer></script>
  </body>
</html>
